C++继承(一)

目录

继承方式

继承同名成员处理方式(父类与子类中都有相同的成员)

继承同名静态成员处理方式

继承中的对象模型

继承中构造和析构函数

菱形继承

多继承语法


在多种接口需要相同输出时,C++的继承相对于传统方式更有利也更方便维护

C++继承语法:

class 子类:继承方式 父类;

传统方式:

class Java{
public:
  void header(){
    cout << "首页、公开课" << endl;
  }
  void footer(){
    cout << "帮助中心" << endl
  }
}

class Python{
  void header(){
    cout << "首页、公开课" << endl;
  }
  void footer(){
    cout << "帮助中心" << endl
  }
}

void test01(){
  cout << "Java下载视频页面如下" << endl;
  Java ja;
  ja.header();
  ja.footer();

  cout << "Python下载视频页面如下" << endl;
  Python py;
  py.header();
  py.footer();  
}



int main(){
  test01();
}

而使用C++继承会显得更加简洁,会让阅读代码的人更加轻松!

C++继承方式:

class BasePage{
public:
  void hearer(){
    cout << "首页、公开课、登陆 "<<end;
  }
  
  void footer(){
    cout << "帮助中心、交流合作" << endl;
  }
  void left(){
		cout << "Java、Python " << endl;
  }
}

class Java : public BasePage{
public:
  void content(){
		cout << "JAVA学科视频 " <<endl;
  }
}

class Python : public BasePage{
public:
  void content(){
    cout << "Python学科视 频 " << endl; 
  }
}

void test01(){
  cout << "JAVA下载视频页面如下:"  << endl;
  Java ja;
  ja.heater();
  ja.footer();
  
  Python py;
  py.heateer();
  py.footer();
}

int main(){
  test01();
  
  return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARVVHT1VBTElDRQ==,size_12,color_FFFFFF,t_70,g_se,x_16

继承方式

C++的继承方式有三种:

public(公开)、protected(保护)、private(私密)

//继承方式

//公共继承
class Base1{
public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;
};

class Son : public Base1{
public:
  void func(){
		m_A = 10;	//父类中的公共权限成员 到子类中依然是公共权限
    m_B = 10;	//父类中的包含权限成员 到子类中依然是保护权限
    m_C = 10;	//子类中的私有权限成员 子类访问不到
  }
};

void test01(){
  Son s1;
  s1.m_A = 100;
  s1.m_B = 100;	//到了son中 m_B是保护权限 类外访问不到
}

//保护继承
class Base2{
  public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;
};

class Son2 : protected Base2{
public:
  void func(){
    m_A = 100;	//父类中公共成员 到子类中变为保护权限
    m_B = 100;	//父类中保护成员,到子类中变为保护权限
    //m_C = 100;	//父类中的私有成员 子类访问不到	
  }
}

void test02(){
  Son2 s1;
  s1.m_A = 100;	//在Son2中m_A变为保护权限,因此类外访问不到
  s1.m_B = 100;	//在Son2中m_B保护权限 不可以访问
}

//私有继承 
class Base3{
 public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;
};

class Son3 : private Base3{
public:
  void func(){
    m_A = 100;	//父类中公共成员 到子类中变为了 私有成员
    m_B = 100;	//父类中保护成员 到子类中变为了 私有成员
    m_C = 100;	//父类中私有成员,子类访问不到
  }
};

class GrandSon3 : public Son3{		//到了son3中 m_A变为私有,即使是儿子 也访问不到
public:
  void func(){
    m_A = 1000;	
    m_B = 1000;
    
  }
}

void test03(){
  s1.m_A = 10000;	//到son3中 变为私有成员 类外访问不到	
  s1.m_B = 120000; //到son3中 变为私有成员 类外访问不到 
}

 总的来说:原本父类中就是private和protected的继承方式,到子类中也无法访问

而子类继承时,如果继承方式为private和protected的都会成为相应的权限类型,而更高的权限则不会变动,如:原本是public方式,但是其中有一个变量是private方式,继承过去的方式是protected,类其中public的会变成protected,但是private的不变。

继承同名成员处理方式(父类与子类中都有相同的成员)

访问子类同名成员 直接访问即可

访问父类同名成员 需要加作用域

//继承中同名成员处理方式
class Base{
public:
  Base(){
		m_A = 100;
  }
  
  void func(){
    cout << "Base-func()调用" << endl;
  }
  
  void func(int a){
    cout << "Base-func(int a) 调用" << endl;
  }
  
  int m_A;
};

class Son : public Base{
public:
  
  Son(){
		m_A = 200;
  }
    void func()
  {
    cout << "Son-func()调用" << endl;
  }
  
  
  int m_A;
}

void test01(){
	Son s;
  cout << "Son下的m_A = "  << s.m_A << endl;
  //如果通过子类对象 访问到父类中同名成员,需要加作用域
  cout << "Base下的m_A = "  << s.Base::m_A << endl;
}

//同名成员属性处理方式
void test02(){
	Son s;
  s.func();	//直接调用 调用是子类中的同名成员
  
  //如何调用到父类中同名成员函数?
  s.Base::func();	//加入作用域
  
  //如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数
  //如果想访问到父类中被隐藏的同名成员函数函数,需要加作用域
  s.Base::func(100);
}

int main(){
	test01();
  
  test02();
}

总结:

  1. 子类对象可以直接访问到子类中同名成员

  2. 子类对象加作用域可以访问到父类同名成员

  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

继承同名静态成员处理方式

静态成员和非静态成员出席同名,处理方式一致

  • 访问子类同名成员,直接访问即可

  • 访问父类同名成员,需要加作用域

  • //继承中的同名静态成员处理方式
    
    class Base{
    public:
      static int m_A;
      
      static void func(){
    		cout << "Base -  static void func()" << endl;
      }
      
      
      static void func(int a){
        cout << "Base - static void func(int a)" << endl;
      }
    };
    
    int Base::m_A = 100;
    
    class Son : public Base{
    public:
    	static int m_A;  
      
      static void func(){
        cout << "Son - static void func()" << endl;
      }
    };
    int Son :: m_A =200;
    
    //同名静态成员属性
    void test01(){
      //1、通过对象访问
      cout << "通过对象访问:"<< endl;
      Son s;
      cout << "Son 下的 m_A= " << s.m_A << endl;
      cout << "Base下的m_A=" << s.Base::m_A << endl;
    
    	//2、通过类名访问
      cout << "通过类名访问" << endl;
      cout << "Son下m_A" << Son :: m_A << endl;
      //第一个::代表通过类名方式访问 第二个::代表访问父类作用域下
      cout << "Base下m_A" << Son :: Base :: m_A << endl;
    }
    //同名静态成员函数
    void test02(){
      //1、通过对象访问
      cout << "通过对象访问" << endl;
      Son s;
      s.func();
      s.Base::func();
      
      //2、通过类名访问
      cout << "通过类名访问" << endl;
      Son::func();
      Son::Base::func();
      
      //子类出现和父类同名静态成员函数,也会隐藏父类中所有同名成员函数
      //如果想访问父类中被隐藏同名成员,需要加作用域
      Son::Base::func(100);
    }
    
    int main(){
      test01();
      
      test02();
    }

    总结:

    同名静态成员处理方式和非静态处理方式一样,只不过有两种访问的方式(通过对象和通过类名)

继承中的对象模型

//继承中的对象模型
class Base{
public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;		//父类中私有的成员属性 是被编译器给隐藏了,因此是访问不到,但是确实被继承下去了
};

class Son : public Base{
public:
  int m_D;
};

void test01(){
  //父类中所有非静态成员属性都会被子类继承下去
  cout << "size of Son=" << sizeof(Son) << endl;	//16 四个变量加起来为16
}

int main(){
  test01();
}

继承中构造和析构函数

子类继承父类后,当创建子类对象,也会调用父类的构造函数

问题:父类和子类的构造和析构顺序是谁先谁后?

//继承中的构造和析构顺序
class Base{
public:
  Base(){
    cout << "Base构造函数!" << endl;
  }
  
  ~Base(){
    cout << "Base析构函数!" << endl;
  }
}

class Son:public Base{
public:
  Son(){
    cout << "Son构造函数!" << endl;
  }
  
  ~Son(){
    cout << "Son析构函数!" << endl;
  }
};

void test01(){
	//Base b;
  //继承中的构造和析构顺序如下:
  //先构造父类,再构造子类,析构的顺序与构造的顺序相反
  Son c;		//会一并创建父类中的构造和析构函数和对象,先有父类再有子类
}

int main(){
	test01();
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARVVHT1VBTElDRQ==,size_16,color_FFFFFF,t_70,g_se,x_16

总结:从上面可以看出父类的构造函数先调用、再是子类的构造函数。而析构函数则相反,先是子类的析构函数先调用、再是父类的析构函数。 

菱形继承

菱形继承概念:

  • 两个派生类继承同一个基类

  • 又有某个类同时继承者

  • 这种继承被称为菱形继承,或者钻石继承

  • watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARVVHT1VBTElDRQ==,size_16,color_FFFFFF,t_70,g_se,x_16

    多继承语法

  • C++允许一个类中继承多个类

  • 多继承语法:

  • class 子类:继承方式 父类1 ,  继承方式 父类2...

    ⚠️:C++实际开发中不建议使用多继承开发

  • //多继承语法
    
    class Base1{
    public:
      Base1(){
        m_A = 100;
      }
      
      int m_A;
    };
    
    class Base2{
    public:
      Base2(){
        m_B = 200;
      }
      
      int m_B;
     
    };
    
    //子类 需要继承Base1和Base2
    //语法:class 子类:继承方式 父类1 , 继承方式 父类2
    class Son : public Base1 , public Base2{
    public:
      Son(){
    		m_C = 300;
        m_D = 400;
      }
    };
    
    void test01(){
      Son s;
      
      cout << "sizeof Son = "<< sizeof(s) << endl
        //当父类中出现同名成员,需要加作用域区分
      cout << "Base1::m_A = " <<s.Base1 :: m_A << endl;	
      cout << "Base2::m_A = " <<s.Base2 :: m_A << endl;
    }
    
    int main(){
      
    }

    总结:多继承中如果父类中出现了同名情况,子类使用时候要加作用域

猜你喜欢

转载自blog.csdn.net/weixin_60154963/article/details/123961925