继承:
从已有类中派生出新的类,新类不仅继承了已有类的所有共有数据域和函数,还可以进行扩展。
基类:被继承的类
派生类:新类
目录
继承语法:
class 派生类: public 基类 #其中红色字体按实际情况替换
多重继承:多个类来得到一个派生类
泛型程序设计:
当程序中需要一个基类对象时,向其提供一个派生类对象
例如,你定义了下列函数,并且Circle类是继承GeometriObject类的
void displayGeometriObject(const GeometriObject& shape){
cout << shape.getColor() << endl;
}
本来该函数是期待接受一个GeometriObject类的对象的,如下:
GeometriObject geo("black",true);
displayGeometriObject(geo);
但根据泛型程序设计理论你也可以创建一个Circle类的对象circle来作为参数,如下:
Circle circle(5);
displayGeometriObject(circle);
构造函数:
派生类的构造函数在执行自身代码之前首先会调用它的基类1的构造函数。
如果该基类1又是某基类2的派生类a,则调用基类1的构造函数之前又会先调用基类2的构造函数,依次类推,这就是构造函数链。
注意:构造函数用于创建类的实例,即对象,并且派生类并不继承基类的构造函数。
派生类的构造函数如何先调用基类的构造函数呢?
DerivedClass(){
}
上面这个简单的构造函数,其实已经隐式的调用了基类的构造方法,因为他和下面这段代码是等价的。
DerivedClass():BaseClass(){
}
第二种就是通过派生类的初始化列表来调用基类的构造函数。
析构函数:
派生类的析构函数首先执行其自身的代码,然后自动调用其基类的析构函数。
析构函数中也有析构函数链的概念,与构造函数链正好相反,他是先调用自身,然后是基类1,基类1的基类这样。
形式:与构造函数一致,不过要在最前面加上符号“~”,例如:
~Circle(double radius){
delete radius;
}
函数的重定义:
在基类中定义的函数能够在派生类中被重新定义,最常用的就是基类中的tostring()函数了。
注意:为了能够在派生类中重定义基类的函数,需要在派生类的头文件中添加函数的原型,并在派生类的实现文件中提供函数的新的实现。
当然也可以在创建的对象是派生类,并且想使用基类起初的函数定义,这时候的语法:基类名和作用域解析运算符(::)
std::cout << circle1.GeometricObject::tostring() << std::endl;
最后就是注意一下重定义和重载的区别:
重定义:在派生类中定义一个与基类具有相同函数名,签名以及返回值类型的函数。
重载:为了提供多个具有相同函数名和返回值类型,但签名不同的函数。