戏(细)说继承
面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。
当我们去创建一个类时候,我们不需要重新去繁琐的编写已经存在的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。我们把这个已经存在的类称之为基类,我们把新定义的类称之为派生类,
基类负责定义所有类共同拥有的成员,而每个派生类定义各自特有的成员。派生类必须通过使用类派生列表明确指出它是从哪个类继承而来,并说明它是公有继承,保护继承还是私有继承。下面是继承可以完成的一些操作:
- 可以再已有类的基础上添加功能。
- 可以给类添加数据。比如说基类马,可以派生一个白马类,在内加入颜色属性:白色
- 可以修改类方法的行为。
当然,以上都可以通过复制修改源代码来完成,但继承机制只需要提供新特性,甚至只看对外接口不用看源码就可以派生出类,添加新特性。
继承代表着object is a 的关系,例如,哺乳动物是动物,家里养的猫狗等宠物也是动物,因此,狗也是动物,等等。
我们可以用一个基类去派生n个派生类,着意味着,派生类可以从多个基类中继承基类中所拥有的数据和函数,当我们定义一个派生类是,我们我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:
class sonclass ::继承类型 Fatherclass1 class
继承类型 是public、protected 或 private 其中的一个,Fatherclass指的是之前定义过的某个类的名称。当我省略继承类型时时,其默认的作用域为private。
派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。
他们三个的不同如下:
访问 | public | protected | private |
---|---|---|---|
同一个类 | yes | yes | yes |
派生类 | yes | yes | no |
外部的类 | yes | no | no |
一个派生类继承了所有的基类方法,但下列情况除外:
- 基类的构造函数、析构函数和拷贝构造函数。
- 基类的重载运算符。
- 基类的友元函数。
对于派生类,我想说的是派生类分为两大部分:
- 一部分是从基类继承而来的成员,
- 另一部分是在声明派生类是增加的部分,
你可以理解为:假设小明是一个基类,他有一个传家宝,然后小明的儿子他对于小明来说,他就是一个小明这个基类的派生类,然后他可以选择去继承这个基类里有的传家宝,当然也可以选择再拥有这个的同时也造一个新的传家包,然后去把他们放到一起,一直去继承给下一个派生类。
构造一个派生类需要做以下三部分工作:
- 从基类接受成员。
派生类会把基类的全部成员(不包括构造函数和析构函数)接收过来,不能选择接收其中的一部分。
- 调整从基类接受的成员。
在派生类中可以改变基类成员在派生类中的访问属性,这就是下面我们要将的指定继承方式来实现的。
如果在派生类中声明了一个与基类成员相同名字的函数,派生类的新成员会覆盖基类的同名成员。
- 在声明派生类时增加的成员
单继承:
单继承及指其派生类只有一个基类,相当于我们再现实生活中我们每个人只有一个父亲一样。所以其儿子继承了其唯一的父亲的所拥有的东西
#include <iostream>
using namespace std;
// 基类
class Father
{
public:
void Fatherget(int w,int h){
width = w;height=h;}
protected:
int width,height;
};
// 派生类
class Rectangle: public Father{
public:
int getArea(){
return (width * height);}
};
int main(void)
{
Rectangle Rect;
Rect.Fatherget(5,7);
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
结果如下:
Total area: 35
我们来看一下其三种继承类型的不同吧
-
三种继承方式不影响子类对父类的访问权限,子类对父类只看父类的访问控制权。
-
继承方式是为了控制子类(也称派生类)的调用方(也叫用户)对父类(也称基类)的访问权限。
-
public、protected、private三种继承方式,相当于把父类的public访问权限在子类中变成了对应的权限。
基类如下:
class Person { public: Person(const string& name, int age) : m_name(name), m_age(age) { } void ShowInfo() { cout << "姓名:" << m_name << endl; cout << "年龄:" << m_age << endl; } protected: string m_name; //姓名 private: int m_age; //年龄 };
当我们用public继承时
class Teacher : public Person { public: Teacher(const string& name, int age, const string& title) : Person(name, age), m_title(title) { } void ShowTeacherInfo() { ShowInfo(); //正确,public属性子类可见 cout << "姓名:" << m_name << endl; //正确,protected属性子类可见 cout << "年龄:" << m_age << endl; //错误,private属性子类不可见 cout << "职称:" << m_title << endl;