面向对象程序设计的4个主要特点:抽象、封装、继承、多态性
//新增数据成员初始化
A a;
pt->display( ); (类A中有成员函数display())
B:public A
pt=&b;
//指针指向派生类对象b
pt->display( );
//(类B中也有display()成员函数)还是调用的是派生类中从基类继承过来的display()因为pt与b中基类部分共享一块内存
继承:
(1) 公用继承(public inheritance)
基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。
(2) 私有继承(private inheritance)
基类的公用成员和保护成员在派生类中成了私有成员。其私有成员仍为基类私有。
(3) 受保护的继承(protected inheritance)
基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。
protected成员等价于private成员都不能在类外直接访问,但有一点不同,protected成员可以被派生类成员函数引用。
构造函数:
用户在声明类时可以不定义构造函数,系统会自动设置一个默认的构造函数,在定义类对象时会自动调用这个默认的构造函数。这个构造函数实际上是一个空函数,不执行任何操作。如果需要对类中的数据成员初始化,应自己定义构造函数
Student(int n,string nam,char s,int a,stringad):Teacher(n,nam,s)
{
}//派生类中构造函数
初始化顺序是: 先调用基类构造函数然后调用派生类构造函数
清理时的顺序: 先调用派生类析构函数然后调用基类析构函数
一个类对象被定义直接调用构造函数,一个类对象被释放直接调用析构函数
一个类对象被定义直接调用构造函数,一个类对象被释放直接调用析构函数
继承引起的二义性:
1 基类的同名成员在派生类中被屏蔽
A:public B
B b;
b ->display();
//调用的是派生类中从基类继承过来的display()
虚基类
如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。
虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。因为一个基类可以在生成一个派生类时作为虚基类,而在生成另一个派生类时不作为虚基类。声明虚基类的一般形式为
class 派生类名: virtual 继承方式 基类名
经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次。为了保证虚基类在派生类中只继承一
次,应当在该基类的所有直接派生类中声明为虚基
类。否则仍然会出现对基类的多次继承。
class 派生类名: virtual 继承方式 基类名
经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次。为了保证虚基类在派生类中只继承一
次,应当在该基类的所有直接派生类中声明为虚基
类。否则仍然会出现对基类的多次继承。
2通过指向基类对象的指针即使让它指向派生类对象,只能访问派生类中的基类成员,而不能访问派生类增加的成员。(注意是访问的派生类中的成员)
A*pt=&a;//定义指向基类A类对象的指针并指向a(pt是a的别名共享一块内存)
3 派生类对象可以向基类对象赋值
A a;
//定义基类A对象a1
B b;
//定义类A的公用派生类B的对象b1
a=b;
//用派生类B对象b1对基类对象a1赋值
并不是说a指向了b,a.display()访问的是基类中的display()而不是派生类中基类display()只是赋值而已
并不是说a指向了b,a.display()访问的是基类中的display()而不是派生类中基类display()只是赋值而已
赋值后不能企图通过对象a去访问派生类对象b的成员,
只能用子类对象对其基类对象赋值,而不能用基类对象对其子类对象赋值,理由是显然的,因为基类对象不包含派生类的成员,无法对派生类的成员赋值。
多态:
当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函
数。定义一个指向基类对象的指针变量,并使它指向不同子类的对象就可以去调用子类中的虚函数了。