继承与派生
一、继承与派生的概念
1、概念
通过下面图片我们可以更形象一点的了解继承与派生:
继承:类的继承,是新的类从已有的类那里得到已有的特性。
派生:从已有的产生新类的过程就是类的派生
由原有的类产生新类时,新类便包含了原有类的特性,同时可以自己所特有的新特性。原有的类称为基类或父类,产生的新类称为派生类或子类。
其继承与派生的好处在简单理解方面就是大大的减少了代码的重复使用,而且在以后的学习中对已有的程序更好的发展与改进。
2、派生的定义
class派生类名:继承方式 基类名1,继承方式 基类名2,……继承方式 基类名n
{
派生类成员声明;
};
class Derived :public Base1,private Base2 { public: Derived(); ~Derived(); };
二、访问控制
1、公有继承
公有继承:当类的继承方式为公有继承时,基类的共有成员和保护成员的访问属性在派生类中不变,而基类的私有成员不可直接访问。
#include <iostream> using namespace std; class Cat { public: void tat(float weight, int age) { this->weight = weight; this->age = age; } float getx() { return weight; } int gety() { return age; }; private: float weight; int age; }; class Vivo :public Cat { public: void inVivo( float weight, int age) { tat(weight, age); } //公有继承 }; using namespace std; int main() { Vivo io; io.inVivo(25.2,8); cout << "Vivo know cat's weight and age:" << io.getx() << "," << io.gety() << endl; return 0; }
运行结果:
class Vivo :public Cat
运用了公有继承,便可以在“Vivo”可以访问“Cat”中的除了私有成员以及构造及析构函数,
从上述代码以及运行结果看得出在继承方向上,使代码更加简洁以及方便,能使代码更好的优化与发展
三种继承方式如下列代码:
#include<iostream> using namespace std; class A { public: A() {}; public: int x; protected: int y; private: int z; }; class B :public A{ public: //公有继承成员函数访问基类的公有成员 (公有继承) int num() { return x; } //访问基类的保护成员 int num2() { return y; } //访问基类的私有成员 // int num3() { return z; } //return z;(在这个访问中会报错)//错误1 }; class C :private A { public: //私有继承成员函数访问基类的公有成员 (私有继承) int num() { return x; } //访问基类的保护成员 int num2() { return y; } //访问基类的私有成员 // int num3() { return z; } //错误2; }; class D :protected A { public: //保护继承成员函数访问基类的公有成员 (保护继承) int num() { return x; } //访问基类的保护成员 int num2() { return y; } //访问基类的私有成员 // int num3() { return z; } //错误3; }; int main(int argc, const char* argv[]) { B b; //公共继承 C c; //私有继承 D d; //保护继承 int var = 0; //公共继承 b.num = var; //D 正确,公有成员公共继承后依然是公有成员,类对象可以访问自身的公有成员 //b.data2 = var; //E 错误,保护成员公共继承后依然是保护成员,类对象不能访问自身的保护成员 var = b.num2(); //F 正确,保护成员继承后依然是保护成员,类对象当然是可以通过类方法访问自身的保护成员的! //私有继承 //c.data1 = var; //G 错误,公有成员私有继承后变成私有成员,类对象不可以访问自身的私有成员 var = c.num2(); //H 正确,保护成员在派生类中变成了私有的,当然可以通过类方法访问自身的私有成员! //保护继承 //d.data1 = var; //I 错误,公有成员保护继承后变成保护成员,类对象不可以访问自身的保护成员 var = d.num2(); //j 正确,基类保护成员在保护派生类中变成了保护的,当然可以通过类方法访问自身的保护成员! return 0; }
公有继承
**注意事项:
- 基类的私有成员,子类不可以访问
- 基类的保护成员,子类可以继承为自己的保护成员,在派生类可以访问,在外部不可以访问。
- 基类的公有成员,子类可以继承为自己的公有成员。在派生类可以访问,在外部也可以访问。
私有继承
**注意事项:
基类公有成员,子类中继承为自己的保护成员,在派生类可以访问,在外部不可以访问
基类保护成员,子类中继承为自己的保护成员,在派生类可以访问,在外部不可以访问
基类私有成员,子类一样不可以访问基类的私有成员。**
私有继承(private)
私有继承方式的,就是在继承时,把protected变成private,它需要注意的事项为:
**(1) 基类公有成员,子类中继承为自己的私有成员,在派生类可以访问,在外部不可以访问。
(2). 基类保护成员,子类中继承为自己的私有成员,在派生类可以访问,在外部不可以访问。
(3) 基类私有成员,子类一样不可以访问基类的私有成员,**
三种继承方式比较
**从上面的结果来看,私有继承和保护继承作用完全一样。仔细一想其实还是有区别,区别是如果派生类再一次去派生其它类时,对于刚才的私有继承来说,再派生的类将得不到任何成员。而对于刚才的保护继承,仍能够得到基类的公有和保护成员。**
三、类型兼容规则
类型兼容规则是指:在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。
类型兼容规则中所指的替代包括:
- 派生类的对象可以隐含转换为基类对象。
- 派生类的对象可以初始化基类的引用。
- 派生类的指针可以隐含转换为基类的指针。
在替代了之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。class B{…}
class D:public B{…}
B b1,*pb1;
D d1;
b1=d1;
B &rb = d1;
pb1=&d1;
-
#include<iostream> using namespace std; class Base1 { public: void display()const { cout << "Base1::display()" << endl; } }; class Base2 :public Base1 { //公有派生类Base的定义 public: void display()const { cout << "Base2::display()" << endl; } }; class Derived :public Base2 { //公有派生类Base的定义 public: void display()const { cout << "Derived::display()" << endl; } }; void fun(Base1* prt) { prt->display(); } int main() { Base1 base1; Base2 base2; Derived derived; fun(&base1); fun(&base2); fun(&derived); return 0; }
运行结果如下: