一、面向对象程序设计的特点:抽象,封装,继承,多态性。
二、3种成员访问限定符及其继承关系:
问题:
private/protected限定符都是限定直接访问,那他们之间有什么区别?
解答:在本类中,private和protected作用是相同的,但是protected可以被继承,而private却不能。
三种继承关系下基类成员的在派生类的访问关系变化如下表所示:
总结:
1.基类的私有成员在派生类中是不能被访问的,如果一些基类成员不想被基类对象直接访问,但需要在派生类中能访问,就定义为保护成员。可以看出保护成员限定符是因继承才出现的。
2.public继承是一个接口继承,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。
3.protetced/private继承是一个实现继承,基类的部分成员并未完全成为子类接口的一部分,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。
4.不管是哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,但是基类的私有成员存在但是在子类中不可见(不能访问)。
5.使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式,在实际运用中一般使用都是public继承,极少场景下才会使用protetced/private继承.
三、继承和派生相关定义举例
类的继承:一个新类从已有的类那里获得其已有特性。
类的派生:从已有的类(父类)产生一个新的子类。
派生类是基类的具体化,基类是派生类的抽象。
继承的3种分类:
单继承:一个派生类只从一个基类派生。
多继承:一个派生类有两个或多个基类。
菱形继承:
声明派生类的一般形式:
class 派生类名:[继承方式] 基类名
{
派生类新增加的成员
}
例1.用公用继承方式,在程序中包括输入数据的函数,运行程序输入num,name,sex,age,addr的值,输出以上5个数据的值。
解:程序:
#include<iostream>
using namespace std;
class Student
{
public:
void get_value()//输入基类的3个私有成员的值
{
cin >> num >> name >> sex;
}
void display()//输出基类的3个私有成员的值
{
cout << "num:" << num << endl;
cout << "name:" << name << endl;
cout << "sex:" << sex << endl;
}
private:
int num;
char name[10];
char sex;
};
class Student1:public Student//定义公用派生类Student1
{
public:
void get_value_1()//函数的作用是输入5个数据成员的值
{
get_value();//调用函数,输入基类的3个私有数据成员的值
cin >> age >> addr;//输入派生类的两个私有数据成员的值
}
void display_1()//输出派生类的2个私有数据成员的值
{
cout << "age:" << age << endl;
cout << "address:" << addr << endl;
}
private:
int age;
char addr[30];
};
int main()
{
Student1 stud1;//定义公用派生类Student1的对象stud1
stud1.get_value_1();//输入5个数据
stud1.display();//输出基类的3个私有数据成员的值
stud1.display_1();//输出派生类2个私有数据成员的值
system("pause");
return 0;
}
结果:
1111 yao M 20 xi'an
num:1111
name:yao
sex:M
age:20
address:xi'an
请按任意键继续. . .
例2.用私有继承方式,在程序中包括输入数据的函数,运行程序输入num,name,sex,age,addr的值,输出以上5个数据的值。
解:程序:
#include<iostream>
using namespace std;
class Student
{
public:
void get_value()
{
cin >> num >> name >> sex;
}
void display()
{
cout << "num:" << num << endl;
cout << "name:" << name << endl;
cout << "sex:" << sex << endl;
}
private:
int num;
char name[10];
char sex;
};
class Student1:private Student//定义私有派生类Student1
{
public:
void get_value_1()
{
get_value();
cin >> age >> addr;
}
void display_1()
{
display();
cout << "age:" << age << endl;
cout << "address:" << addr << endl;
}
private:
int age;
char addr[30];
};
int main()
{
Student1 stud1;
stud1.get_value_1();
stud1.display_1();//只需调用一次stud1.display_1()
system("pause");
return 0;
}
结果:
1111 yao M 20 xi'an
num:1111
name:yao
sex:M
age:20
address:xi'an
请按任意键继续. . .
例3.用保护继承方式,在程序中包括输入数据的函数,运行程序输入num,name,sex,age,addr的值,输出以上5个数据的值。
解:程序:
#include<iostream>
using namespace std;
class Student//声明基类
{
public://基类公用成员
void get_value();
void display();
protected://基类保护成员
int num;
char name[10];
char sex;
};
void Student::get_value()
{
cin >> num >> name >> sex;
}
void Student::display()
{
cout << "num:" << num << endl;
cout << "name:" << name << endl;
cout << "sex:" << sex << endl;
}
class Student1:protected Student//声明一个保护派生类Student1
{
public:
void get_value_1();
void display_1();
private:
int age;
char addr[30];
};
void Student1::get_value_1()
{
get_value();
cin >> age >> addr;
}
void Student1::display_1()
{
cout << "num:" << num << endl;
cout << "name:" << name << endl;
cout << "sex:" << sex << endl;
cout << "age:" << age << endl;
cout << "address:" << addr << endl;
}
int main()
{
Student1 stud1;
stud1.get_value_1();
stud1.display_1();
system("pause");
return 0;
}
结果:
1111 yao M 20 xi'an
num:1111
name:yao
sex:M
age:20
address:xi'an
请按任意键继续. . .
四、继承与转换--赋值兼容规则:
1.子类对象可以赋值给父类对象,父类对象不能赋值给子类对象;
2.父类的指针/引用可以指向子类对象,子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
五、继承体系中的作用域:
1.在继承体系中基类和派生类都有独立的作用域。
2.子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用 基类::基类成员 访问)--隐藏
注意:在实际中在继承体系里面最好不要定义同名的成员。
六、派生类的6个默认成员函数
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。