继承与派生
派生类的声明方式
一般形式:
class 派生类名:[继承方式] 基类名{
派生类新增加的成员
};
继承方式包括:public(公有的),private(私有的),protected(受保护的),若不写此项,则默认为private(私有的)
派生类的构成
构造一个派生类包括以下3部分工作:
- 从基类接收成员
- 调整从基类接收的成员
- 在声明派生类是增加的成员
派生类是抽象基类的具体实现
派生类成员的访问属性
公有继承
采用公有继承方式时,基类的公有成员和保护成员在派生类中任然保持其公有成员和保护成员的属性,而基类的私有成员在派生类中并没有成员派生类的私有成员,它任然是基类的私有成员,只能通过基类的成员函数才能调用它,而不能被派生类的成员函数所引用。
私有继承
私有基类的公有成员和保护成员在派生类中的访问属性相当于派生类中的私有成员,即派生类的成员函数能访问它们,而派生类外不能访问它们。私有基类的私有成员在派生类中成为不可访问的成员,只有基类的成员函数才能引用它们。
保护成员和保护继承
保护基类的公有成员和保护成员在派生类中都成为了保护成员,其私有成员任为基类私有,也就是把基类原有的公有成员也保护起来,不让类外任意访问。
多级派生时的访问属性
- 在多级派生时都采用公有继承方法,那么直到最后一级派生类都能访问基类的公有成员和保护成员。
- 在多级派生时都采用私有继承方法,那么经过若干次派生后,基类的所有的成员已经变成不可访问的了。
- 在多级派生时都采用保护继承方法,在派生类外是无法访问派生类内的任何成员的。
因此在实际中常使用公有继承
派生类的构造函数
派生类构造函数的一般形式:(无子对象)
派生类构造函数名 (总参数表):基类构造函数名(参数名){
派生类中新增数据成员初始化语句
}
派生类构造函数的一般形式:(有子对象)
派生类构造函数类(总参数表):基类构造函数名(参数表),子对象名(参数表){
派生类中新增数据成员初始化语句
}
多重继承
声明多重继承的方法
例:(已声明了类A,类B,类C,可以声明多重继承的派生类D)
class D:public A,private B,protected C{
类D新增加的成员
}
多重继承派生类的构造函数
一般形式:
派生类构造函数名(总参数表):基类1构造函数(参数表),基类2构造函数(参数表),基类3构造函数(参数表){
派生类中新增数据成员初始化语句
}
虚基类
虚基类的作用:
在继承间接共同基类时只保留一份成员
声明虚基类的一般方法:
class 派生类名:virtual 继承方式 基类名
当基类通过多次派生路径被一个派生类继承是时,该派生类中继承该基类一次,基类成员只保留一次
为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类。否则任然会出现对基类的多次继承。
基类与派生类的转换
只有公有继承才是基类真正的子类型,它完整地继承了基类的功能
基类和派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类对象的值赋给基类对象,在用到基类对象的时候可以用其子类对象代替
具体表现在以下几个方面:
- 派生类对象可以向基类对象赋值
只能用子类对象对其基类对象赋值,而不能用基类对象对其子类对象赋值,同理,同一基类的不同派生类对象之间也不能赋值 - 派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化
- 如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象
- 派生类对象的地址可以赋给指向基类对象的指针变量,也就是说,指向基类对象的指针变量也可以用来指向派生类对象
继承与组合
在一个类中以另一个类的对象作为数据成员的,称为类的组合。
例:(声明professor类是teacher类的派生类,另有一个类birthday,包含year,month,day等数据成员。可以将教授生日的信息加入到professor类的声明中)
class teacher{ //声明教师类
public:
……
private:
int num;
string name;
char sex;
};
class birthdate{ //声明生日类
public:
……
private:
int year;
int month;
int day;
};
class professor:public teacher{ //声明教授类
public:
……
private:
birthdate birthday; //birthdate类的对象作为数据成员
}
继承是纵向(xx是xx)的关系,组合是横向(xx有xx)的关系