来源
继承是从生活中演化而来的概念,大家说狗的时候,大家都有一个概念:四条腿,一条尾巴,哺乳动物,会叫。大家说黑狗的时候大家不会说黑狗是:毛色是黑的四条腿,一条尾巴,哺乳动物会叫的动物。大家都会说黑色的狗。
这里狗就是基类,黑狗就是派生类,派生类是基类的一个特例。黑狗继承了狗的四条腿,一条尾巴,哺乳动物的属性。
派生类
为什么用派生
方便根据大家熟悉的基类来描述基类的一个特例派生类;比如:大家都知道狗这个概念,这时候在去描述黑狗这个派生概念的时候,只要说出与基类黑狗的不同之处就可以了。不必把已熟知的狗的属性再说一遍,因为这些属性方法已经全部继承给了黑狗。
不同之处
- 增加新的成员(数据成员或成员函数)
- 重新定义已有的成员函数
- 改变基类成员的访问权限
继承方式
单一继承
概念:一个派生类值继承与一个基类
- 类的保护成员
- public:用它修饰的基类成员,不仅可以被派生类使用还可以被外部函数使用
- private:用它修饰的基类成员,只能被基类使用,派生类虽然可以继承,但是不可以使用
- protect:基类用它修饰的成员,只能被基类继承使用,外部函数不可以调用。
- 派生类别
- 共有派生:基类所有的数据成员按基类本身的访问级别继承给派生类,基类中用public修饰的数据成员和成员函数在派生类中依然是公有的。私有的成员仍然是私有的。
- 私有派生:基类中所有的数据成员在派生类中都是私有的。
- 保护派生:基类中的数据成员在派生类中保护级别降级。public降为protect,protect降为private,private仍然为private;
- 使用类的权限(补)
- 类本身的成员可以使用类的所有成员(私有成员和公有成员)
- 类的对象只能访问公有成员函数
- 其他函数不能访问类的私有成员,也不能使用类的公有函数,它们只能通过类来访问。
- 一个类可以包含一个类的对象,但是这个类也只能通过被包含类的对象来访问那个类的成员函数,通过成员函数来访问数据成员。
- 赋值兼容规则(ISA)
- 派生类的对象可以赋值给基类的对象
- 派生类的对象可以初始化基类的引用
- 派生类的对象的地址可以赋值给指向基类的指针
- eg:黑狗是从狗继承来的,把黑狗的对象赋值给狗,这时候让狗叫也就是让黑狗叫,调用的是狗的方法,但是使用的是黑狗的属性。
- hasa
- 狗有牙齿,但是不能让狗继承牙齿这个类,而是让狗拥有牙齿这个类,让牙齿类作为狗的属相对象。一个类可以拥有很多个对象属性。
多重继承
概念:一个类从多个基类派生。
格式:class 类名1:访问控制(public/private/protect) 类名2,访问控制 类名3,…访问控制 类名n
{//定义派生类自己的成员}
二义性
对基类成员的访问必须是无二义性的,如果各个基类有相同的成员,这种访问就具有二义性。
#include<iostream>
using namespace std;
class A{
public:
void func(){cout<<"a.func"<<endl;}
};
class B{
public:
void func(){cout<<"b.func"<<endl;}
void gunc(){cout<<"b.gunc"<<endl;}
};
class public A,public B{
public:
void gunc(){cout<<"c.gunc"<<endl;}
void hunc(){func();}//此时调用func()就会出现二义性,不知道调用的是哪个基类的func();
};
//-----------------------------------消除二义性---------------------------------------------------
class public A,public B{
public:
void gunc(){cout<<"c.gunc"<<endl;}
void hunc(){A::func();}//使用基类A的func
void hunc1(){B::func();}//使用基类B的func
};
小结
学而时习之不亦说乎。每次学习不同的知识发现相同之处真的很开心啊!