首页 > 其他分享 >类和对象——继承

类和对象——继承

时间:2022-11-13 16:13:14浏览次数:67  
标签:访问 继承 子类 成员 同名 对象 父类

概念:有些类与类之间存在特殊关系(如例图)

 

 这些类在定义的时候,下级别的成员除了拥有上一级的共性,还有自己的特性。。

此时采用继承的技术,可以减少重复的代码片段。

就像一个网页,多个页面只有中心内容不同,其他部分(导航,悬浮工具栏,底部等)全部相同。。

>>>>>>>>>>>>>>1.语法:<<<<<<<<<<<<<<<<

子类也叫派生类;

父类也叫基类;

例子(两种方式实现的效果一致):

(采用传统页面:每个页面都是一个新的类)

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 //爪哇类
 6 class Java{
 7 public:
 8     void header(){
 9         cout << "公共头部~" << endl;
10     }
11     void footer(){
12         cout << "~公共底部" << endl;
13     }
14     void left(){
15         cout << "~公共左侧~" << endl;
16     }
17     void content(){
18         cout << "~~Java独有部分~~" << endl;
19     }
20 };
21 
22 //python类
23 class Python{
24 public:
25     void header(){
26         cout << "公共头部~" << endl;
27     }
28     void footer(){
29         cout << "~公共底部" << endl;
30     }
31     void left(){
32         cout << "~公共左侧~" << endl;
33     }
34     void content(){
35         cout << "~~Python独有部分~~" << endl;
36     }
37 };
38 
39 void test01(){
40     Java Ja;
41     cout << "爪哇部分:" << endl;
42     Ja.header();
43     Ja.footer();
44     Ja.left();
45     Ja.content();
46 
47     cout << "=============" << endl;
48 
49     Python py;
50     cout << "py部分:" << endl;
51     py.header();
52     py.footer();
53     py.left();
54     py.content();
55 }
56 
57 int main(){
58     test01();
59     system("pause");
60     return 0;
61 }

(采用继承)

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 //继承实现
 6 //公共类
 7 class BasePage{
 8 public:
 9     void header(){
10         cout << "公共头部~" << endl;
11      }
12     void footer(){
13         cout << "~公共底部" << endl;
14     }
15     void left(){
16         cout << "~公共左侧~" << endl;
17     }
18 };
19 
20 //Java页面:
21 class Java : public BasePage{
22 public:
23     void content(){
24         cout << "Java特有部分" << endl;
25     }
26 };
27 //python页面:
28 class Python : public BasePage{
29 public:
30     void content(){
31         cout << "Python特有部分" << endl;
32     }
33 };
34 
35 void test01(){
36     Java Ja;
37     cout << "爪哇部分:" << endl;
38     Ja.header();
39     Ja.footer();
40     Ja.left();
41     Ja.content();
42 
43     cout << "=============" << endl;
44 
45     Python py;
46     cout << "py部分:" << endl;
47     py.header();
48     py.footer();
49     py.left();
50     py.content();
51 }
52 
53 int main(){
54     test01();
55     system("pause");
56     return 0;
57 }

2.继承方式

语法:

 

 三类继承方式(对应三类类权限)

● 公共继承

● 保护继承

● 私有继承:

 

说明:

※父类中的私有权限的内容,子类三种继承方式都不能访问(但是都会继承下来,有,但是访问不到),因此下列说明均不包括父类的私有权限的成员

①.公共继承:成员在父类是怎样的,在子类就是怎样的(如图中a是父类的公共成员,b是父类的包含成员,那么在子类中,a是子类的公共成员,b是子类的保护成员)。。

②.保护继承:成员不管在在父类中是什么权限,在子类中均属于保护权限。。

③.私有继承:成员不管在在父类中是什么权限,在子类中均属于私有权限。。

④.类嵌套过程中,务必确认继承的上一级的类的成员权限。


3.继承中的对象模型:

案例:

 

最终输出16:int m_A + int m_B + int m_C + int m_D = 4字节 + 4字节 + 4字节 + 4字节 = 16字节

说明子类会完全继承父类中的非静态成员属性,父类的私有成员属性给编译器隐藏了,无法访问,但是还是会被继承。。


4.继承中的构造和析构顺序

先构造父类,再构造子类,析构相反(先析构子类,再析构父类)


5.继承同名成员的处理方式(子类和父类中出现同名成员,非静态)

● 访问子类同名成员,直接访问

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

案例1(同名属性):

 

 案例2(同名函数):

 

注意事项:

如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数(包括父类中重载的函数)

如果想访问到父类中被隐藏的同名成员函数,则需要加作用域。。

完整版案例:

 

 

 

 别忘了自己写主函数。。。


6.继承同名静态成员的处理

静态成员和非静态成员出现同名的处理方法完全一致。。。

● 访问子类同名成员,直接访问

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

注意静态成员的两类访问方式均可以使用(对象访问、类名访问)

案例:

 


7.多继承语法

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

语法:

 

注意:多继承可能会引发父类中同名成员的出现,要加作用域以区分。。

案例:

 

 

 


8.菱形继承/钻石继承

概念:两个子类B和C继承同一个父类A,同时又有一个子类D继承了B和C

 

存在的问题:

①B继承了A的数据,C也继承了A的数据,当D使用数据时,会产生二义性。。

②D继承了两份A的数据,但是实际上我们只希望它只继承一份。。

例子:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class AAA{
 6 public:
 7     int m_Age;
 8 };
 9 //利用虚继承解决菱形继承问题
10 //在继承前加上关键字 virtual变为虚继承
11 //此时AAA类称为虚父类/虚基类
12 //在DDD中,BBB和CCC从父类AAA中继承的m_Age变成共享,即d.m_Age = 28
13 class BBB : virtual public AAA{};
14 
15 class CCC : virtual public AAA{};
16 
17 class DDD : public BBB, public CCC{};
18 
19 void test01(){
20     DDD d;
21     d.BBB::m_Age = 18;
22     d.CCC::m_Age = 28;
23     //存在两个父类拥有相同数据时,要加作用域以区分
24     cout << "d.BBB::m_Age =" << d.BBB::m_Age << endl;
25     cout << "d.CCC::m_Age =" << d.CCC::m_Age << endl;
26 
27     cout << d.m_Age << endl;    //需要存在虚继承才能使用,否则报错
28 
29     //但是我们只需要一份m_Age,菱形继承会导致资源浪费
30 }
31 
32 int main(){
33     test01();
34     system("pause");
35     return 0;
36 }

在内存布局中:

 

相当于现在采用了虚基类表,保存了类中成员的偏移量,让指针指向这个偏移量,在调用的时候,避免了二义性的发生。。

 

标签:访问,继承,子类,成员,同名,对象,父类
From: https://www.cnblogs.com/MorningMaple/p/16886156.html

相关文章

  • 类和对象——C++运算符重载
    概念:对已有的运算符重新定义,赋予其另一种功能,以适应不同数据类型。。重载的两类方法:1.类成员函数重载2.全局函数重载注意:运算符重载也可以实现函数重载引入:我们希望......
  • java——继承与多态——接口001
    接口概述与生活举例:                            接口的定义基本格式:            ......
  • <三>对象的浅拷贝和深拷贝问题
    先看示例代码点击查看代码#include<iostream>#include<cstring>usingnamespacestd;classStudent{public:Student(int_age,constchar*_name)......
  • 第6章Spring与Web-使用 Spring 的监听器 ContextLoaderListener使得将spring容器对象
    第6章Spring与Web在Web项目中使用Spring框架,首先要解决在web层(这里指Servlet)中获取到Spring容器的问题。只要在web层获取到了Spring容器,便可从容器中获取到......
  • LayaBox引擎3D源码阅读(一、从继承链开始学习)
    前言在转到3D游戏开发的时候,始终会有所不适,首先最难让人不习惯的就是,空间的转换没办法那么快的就转换过来。另一个始终是分不清纹理,材质,网格,贴图这些名词之间到底什么关系......
  • 02类与对象-动手动脑
    代码:classRoot{ static { System.out.println("Root的静态初始化块"); } { System.out.println("Root的普通初始化块"); } publicRoot() { System.out.println("Root......
  • 02-类与对象-一个有趣的问题
    静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)? 代码:package test; publicclassjingtaihanshu{in......
  • 02类与对象--ObjectEquals
    代码:publicclassObjectEquals{ publicstaticvoidmain(String[]args) { MyTestClassobj1=newMyTestClass(100); MyTestClassobj2=newMyTestClass(100);......
  • 02类与对象--动手动脑
      原因:在主函数下面定义了一个自定义的Foo()构造方法,将导致系统不再默认提供构造方法修改方法:1.删除Foo(int)的定义 2.再敲一下Foo()默认构造函数......
  • 02-类与对象 进行试验--Java字段初始化的规律
    1.类的构造方法(1)“构造方法”,也称为“构造函数”,当创建一个对象时,它的构造方法会被自动调用。构造方法与类名相同,没有返回值。(2)如果类没有定义构造函数,Java编译器......