十五、继承和派生,兼容性原则

  1. 类和类的关系
  2. 继承
    2.1 定义
    2.2 派生类的组成
    2.3 几点说明
  3. 继承的方式
    3.1 protected 访问控制
    3.2 派生类成员的标识和访问
  4. 练习
  5. 继承中的构造和析构
    5.1 类型兼容性原则
    5.2 初始化父类成员,父类与子类的构造函数的关系
    5.3 继承中同名成员变量处理方法
    5.4 派生类中的static关键字
    5.5 多继承

在 C++中可重用性(software reusability)是通过继承(inheritance)这一机制来实现的。 如果没有掌握继承性,就没有掌握类与对象的精华。

1.类和类之间的关系

has-A uses-A is-A

  • has-A 包含关系,用以描述一个类由多个“部件类”构成。实现has-A关系用类成员表示,即一个类中的数据成员是另一种已经定义的类。
  • uses-A 一个类部分地使用另一个类。通过类之间成员函数的相互联系,定义友员或对象参数传递实现。
  • is-A 机制称为“继承”。关系具有传递性,不具有对称性。

2.继承

#include 
#include 
using namespace std;
class Student
{
   public:
   Student(int age,string name){
        this->age = age;
        this->name = name;
    }

    void printS(){
      cout<sex = s;
       this->score = f;
     }
  void printS(){
     Student::printS();
     cout<sex<score<
2.1定义

类的继承,是新的类从已有类那里得到已有的特性。或从已有类产生新类的过程就是类的派生。原有的类称为基类或父类,产生的新类称为派生类或子类。

派生与继承,是同一种意义两种称谓。isA 的关系。

十五、继承和派生,兼容性原则_第1张图片
1.png
2.2派生类的组成

派生类中的成员,包含两大部分,一类是从基类继承过来的,一类是自己增加的成员。从基类继承过过来的表现其共性,而新增的成员体现了其个性。

十五、继承和派生,兼容性原则_第2张图片
2.png
2.3 几点说明:
  • 全盘接收,除了构造器与析构器。基类有可能会造成派生类的成员冗余,所以说基类是需设计的。
  • 派生类有了自己的个性,使派生类有了意义。

3.继承的方式

class 派⽣生类名:[继承⽅方式] 基类名{
    派⽣生类成员声明;
};

一个派生类可以同时有多个基类,这种情况称为多重继承,派生类只有一个基类, 称为单继承。下面从单继承讲起。

3.1protected 访问控制

protected 对于外界访问属性来说,等同于私有,但可以派生类中可见。

#include 
using namespace std;
class Base {
 public://访问控制权限
    int pub;//对内部外部均可以
 protected:
    int pro;//对内可以,外不可以//protected访问控制权限下的成员 儿子可见
 private:
    int pri;//对内外 均不可以
};

class Drive:public Base{
  public:
     void  func(){
        pub = 10;
        pro = 100;
       //pri=1000;//error
     }
};

//三看原则
//1 看当前的成员调用的是类的外部 还是在类的内部
//2 看儿子的继承方式,是公有继承还是 私有继承
//3 看当前的额成员变量在父亲中的访问控制权限


//1 基类的私有成员 不管子类如何继承,子类都访问不了。
//2 如果是公有继承,那么基类中的访问控制权限,除了私有成员,在子类中保持不变
//3 如果是保护继承protected,那么子类中除了基类的私有成员,全部是protected权限
//4 如果是私有继承private,父类中除了私有成员,在子类都是私有成员
int main(void)
{
    Base b;
    b.pub = 10;
  //b.pro = 100;//error
  //b.pri = 1000;//error

   return 0;
}
3.2派生类成员的标识和访问
---- public protected private
公有继承(public) public protected 不可见
保护继承(protected) protected protected 不可见
私有继承(private) private private 不可见

public公有继承
当类的继承方式为公有继承时,基类的公有和保护成员的访问属性在派生类中不变,而基类的私有成员不可访问。即基类的公有成员和保护成员被继承到派生类 中仍作为派生类的公有成员和保护成员。派生类的其他成员可以直接访问它们。无 论派生类的成员还是派生类的对象都无法访问基类的私有成员。

private私有继承
当类的继承方式为私有继承时,基类中的公有成员和保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可访问。。基类的公有成员和保 护成员被继承后作为派生类的私有成员,派生类的其他成员可以直接访问它们,但 是在类外部通过派生类的对象无法访问。无论是派生类的成员还是通过派生类的对 象,都无法访问从基类继承的私有成员。通过多次私有继承后,对于基类的成员都 会成为不可访问。因此私有继承比较少用。

protect保护继承
保护继承中,基类的公有成员和私有成员都以保护成员的身份出现在派生类中,而基类的私有成员不可访问。派生类的其他成员可以直接访问从基类继承来的 公有和保护成员,但是类外部通过派生类的对象无法访问它们,无论派生类的成员 还是派生类的对象,都无法访问基类的私有成员。

private成员在子类中依然存在,但是却无法访问到。不论何种方式继承基类,派生类都不能直接使用基类的私有成员。

如何恰当的使用public,protected和private为成员声明访问级别?

  • 需要被外界访问的成员直接设置为public
  • 只能在当前类中访问的成员设置为private
  • 只能在当前类和子类中访问的成员设置为protected,protected成员的访问权限介于public和private之间。

4.练习

#include 
using namespace std;

class A
{
private:
    int a;
protected:
    int b;
public:
    int c;
    A(){
      a = 0;
      b = 0;
      c = 0;
     }
   void set(int a,int b,int c){
     this­‐>a = a;
     this­‐>b = b;
     this‐>c = c;
   }
};


class B:public A
{
public:
    void print()
    {
      cout<<"a = "<printP();
}

int main(void)
{
    Child c;//子类对象
  
    c.printP(); //子类对象可以当作父类对象使用(方法继承)

   //子类对象可以直接赋值给父类对象
    Parent p = c;
  //Child c2 = p;报错!
  //由于子类用于父类的全部内存空间,子类能够保障父类初始化完成
  //子类对象可以直接初始化父类对象,因为子类内存空间包含的父类的内存空间,能够保证完全赋值
 

 //父类指针可以直接指向子类对象
 //子类对象能够完全满足父类指针的需求,所以可以
Parent *pp = &c;//pp->printP,pp->printC不存在这个方法

//不能用子类指针指向父类对象
//父类对象满足不了子类指针的所有需求,所以不能够
Child *cp = &p;//报错!cp->printP,cp->printC
//cp指向父类对象,父类是没有printC方法的!所以报错


//父类引用可以直接引用子类对象
  Parent &pr = c;
  
//子类引用不可以引用父类的对象
  Child &cr = p;//报错,和父类指针一样

//利用兼容性原则传参!
  print(&p);//Parent *p = &p;
  print(&c);//Parent *p = &c;

   return 0;
}
5.2初始化父类成员,父类与子类的构造函数有什么关系?
十五、继承和派生,兼容性原则_第3张图片
3.jpg
十五、继承和派生,兼容性原则_第4张图片
4.png
  • 在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化.
  • 在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理.
//子类在进行初始化成员变量的时候,如果此成员变量是继承过来的,那么需要调用父类的构造器来初始化
class Parent
{
public:
  Parent(int a){
     this->a = a;
     cout<<"Parent(int a)..."< 
  
十五、继承和派生,兼容性原则_第5张图片
5.png
class Funiture
{
public:
   int m;//材质
};//如果子类虚继承本类,编译器会将父类中的成员,只拷贝一份


//沙发床
//床类
class Bed:virtual public Funiture
{
public:
  void sleep(){
      cout<<"在床上睡觉..."<
十五、继承和派生,兼容性原则_第6张图片
6.png
十五、继承和派生,兼容性原则_第7张图片
7.jpg

你可能感兴趣的:(十五、继承和派生,兼容性原则)