C++基础13-类和对象之继承2
总结:
1、子类对象可以当做父类对象使用
2、子类对象可以直接赋值给父类对象
3、子类对象能够直接初始化父类对象
4、父类指针可以直接指向子类对象
5、凡是继承过来的属性和函数都可以在子类中用this-> 进行访问
6、默认构造函数并不会初始化数据成员
7、如果子类数据成员和父类数据成员名称相同。在子类用利用:: 访问父类数据成员,this-> 默认为子类数据成员
8、构造函数和析构函数不会被继承
一、类型兼容性规则
类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
类型兼容规则中所指的替代包括以下情况:
<1>子类对象可以当作父类对象使用
<2>子类对象可以直接赋值给父类对象
<3>子类对象可以直接初始化父类对象
<4>父类指针可以直接指向子类对象
<5>父类引用可以直接引用子类对象
继承模型:
在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化.
在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理.
二、继承中构造析构调用原则
1、子类对象在创建时会首先调用父类的构造函数
2、父类构造函数执行结束后,执行子类的构造函数
3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
4、析构函数调用的先后顺序与构造函数相反
总原则:
先构造父类,再构造成员变量、最后构造自己
先析构自己,在析构成员变量、最后析构父类
三、继承中同名成员变量处理方法
1、当子类成员变量与父类成员变量同名时 ,子类依然从父类继承同名成员
2、在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式地使用类名限定符)
注:同名成员存储在内存中的不同位置
四、派生类中的static关键字
1、基类定义的静态成员,将被所有派生类共享
2、根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)
3、 派生类中访问静态成员,用以下形式显式说明:
类名 :: 成员
或通过对象访问 对象名 . 成员
示例:
1、类的兼容性规则
#if 1
#include<iostream>
using namespace std;class Parent {
public:void printP() {cout << "a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:/*void printP() {cout << "b:" << this->b << endl;}*/void printC() {cout << "b:" << this->b << endl;}int b;
};
void test01() {Parent *p = new Child;p->printP(); //子类和父类都有printP函数时,调用父类的成员函数
}
//子类对象可以当做父类对象使用
//子类对象可以直接赋值给父类对象
//子类对象能够直接初始化父类对象
void test02() {Parent p; //父类空间小//Child c = p; //子类空间大于父类,不能够全部初始化,所以报错Child c;Parent p = c; //c对象占用空间>=p对象占用空间 //能够填充可以通过编译//子类对象能够直接初始化父类对象c.printP(); //c能够当做父类p来使用}
//父类指针可以直接指向子类对象
//好处:
void test03() {Parent *pp = NULL; //父类指针Child *cp = NULL; //子类指针Parent p; //父类对象Child c; //子类对象cp = &c;//cp = &p; 子类指针指向父类对象 错误 子类指针访问范围大于父类对象的范围//原来cp的访问权限为cp->a,cp->b,cp->printP.cp->printC//cp指向p时,cp的访问权限只能为cp->a,cp->printP//会访问越界pp = &p;pp = &c; //通过编译 父类指针指向子类对象//原来cp的访问权限为pp->a; pp->printP//pp指向c时,cp的访问权限扔为pp->a; pp->printP//c内存布局能够满足父类指针的全部需求 可以用一个儿子的对象地址给父类指针赋值}
int main() {return 0;
}
#endif
2、构造函数和析构函数
#if 0
#include<iostream>
using namespace std;
//在调用子类的构造函数时 一定会调用父类的构造函数
//父类先构造,子类再构造
//析构和构造顺序相反
class Parent {
public:Parent() {cout << "Parent()... " << endl;a = 0;}Parent(int a) {cout << "Parent(int a)..." << endl;this->a = a;}int a;~Parent() {cout << "~Parent()..." << endl;}
};
class Child :public Parent {
public://在调用子类的构造函数时 编译器会默认调用父类无参构造
#if 0Child(int a,int b) {cout << "Child(int a,int b)..." << endl;this->a = a;this->b = b;}
#endif//显示调用父类有参构造Child(int a ,int b):Parent(a){cout << "Child(int a,int b)..." << endl;this->b = b;}~Child() {cout << "~Child()... " << endl;}void printC() {cout << "b=" << b << endl;}int b;
};//在调用子类时 编译器会默认调用父类无参构造
void test01() {Child c(10, 20);c.printC();
}
/*
Parent()...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
//显示调用父类有参构造
void test02() {Child c(10, 20);c.printC();
}
/*
Parent(int a)...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
int main() {test01();return 0;
}
#endif
3、子类和父类成员重名
#if 0
#include<iostream>
using namespace std;
#if 0
class Parent {
public:Parent() {cout << "Parent() " << endl;this->a = 0;}Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int a) {cout << "Child(int a)" << endl;this->a = a;}~Child() {cout << "析构子类a:" << this->a << endl;}
};void test01() {Child c(2);
}
/*
Parent()
Child(int a)
析构子类a:2
析构父类a:0
*/
#endif
#if 0
class Parent {
public:Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int p_a,int c_a):Parent(p_a){cout << "Child(int a)" << endl;this->a = c_a;}~Child() {cout << "析构子类a:" << this->a << endl;}void print() {cout << "父类a:"<<Parent::a << endl;cout <<"子类a:" <<this->a << endl; //子类的a}
};void test01() {Child c(2,3);c.print();
}
/*
Parent(int a)
Child(int a)
父类a:2
子类a:3
析构子类a:3
析构父类a:2
*/
#endif
//子类和父类函数名相同调用
class Parent {
public:Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}void print() {cout << "父类print" << endl;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int p_a, int c_a) :Parent(p_a) {cout << "Child(int a)" << endl;this->a = c_a;}~Child() {cout << "析构子类a:" << this->a << endl;}void print() {cout << "子类print" << endl; //子类的a}
};void test01() {Parent p(1);p.print();cout << "------" << endl;Child c(2, 3);c.Parent::print();c.print();
}
/*
Parent(int a)
父类print
------
Parent(int a)
Child(int a)
父类print
子类print
析构子类a:3
析构父类a:2
析构父类a:1
*/
int main() {test01();return 0;
}
#endif
4、继承中的static成员
#if 1
#include<iostream>
using namespace std;
#if 0
class A {
public:static int a;
private:
};
int A::a = 0; //静态成员变量 初始化void test01()
{A a1;A a2;cout << a1.a << endl;cout << a2.a << endl;a1.a = 300;cout << a1.a << endl;cout << a2.a << endl;
}
/*
0
0
300
300
*/
#endifclass A {
public:static int a;
private:
};
class B :public A {
public:
private:
};
int A::a = 0; //静态成员变量 初始化void test01()
{A a1;A a2;cout << a1.a << endl;cout << a2.a << endl;a1.a = 300;cout << a1.a << endl;cout << a2.a << endl;B b1;B b2;cout << b1.a << endl;cout << b2.a << endl;A::a = 400;cout << b1.a << endl;cout << b2.a << endl;
}
/*
0
0
300
300
300
300
400
400
*/
int main() {test01();return 0;
}
#endif
C++基础13-类和对象之继承2相关推荐
- 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法
python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...
- JAVA基础七 类和对象
文章目录 JAVA基础七 类和对象 01 引用 02 继承 03 方法重载 04 构造方法 05 this 06 传参 07 包 08 访问修饰符 09 类属性 10 类方法 11 属性初始化 12 ...
- Racket编程指南——13 类和对象
13 类和对象 本章基于一篇论文[Flatt06]. 一个类(class)表达式表示一类值,就像一个lambda表达式一样: (class superclass-expr decl-or-expr . ...
- c++入门(类和对象and继承)
文件名:<1> time.h :<2> time.cpp :<3> DateTime.h :<4> DateTime.cpp :<5> ma ...
- java基础(类与对象、集合)
java基础(类与对象.集合) 类与对象 类与对象中的栈和堆 构造方法 this关键字 面向对象三大特性 封装性(private) 继承性(extends) 方法重写(@override) 多态性 向 ...
- python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态
六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...
- JAVA基础––从类和对象开始
JAVA基础--从类和对象开始 一.概念 1.面向对象中类和对象的概念 对象:对象是具有状态和行为的实体,例如某个具体的学生,或者是王者荣耀里的英雄,可以是物理实体,也可以是逻辑实体. 类:类是一组具 ...
- Java_面向对象基础(类、对象、方法和构造函数)
Java的面向对象基础(类.对象.方法和构造函数) 面向对象的基本概念 面向对象的设计思想 什么是类 什么是对象 类的定义 设计面向对象的例子 步骤一:设计动物这个类 步骤二:创建具体的动物 步骤三: ...
- python入门笔记——类和对象⑤(继承)
python入门笔记--类和对象⑤(继承) # python中展现面向对象的三大特征:封装.继承.多态 # 封装:把内容封装到某个地方以便后续的使用 # 对封装来说,其实就是使用初始化构造方法将内容封 ...
- 【C++基础】类和对象——友元
[C++基础]类和对象--友元 友元的概念 在C++中,不能被外部访问的私有属性,通过友元可以访问. 友元的关键字:friend 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 一.全局函数 ...
最新文章
- qdockwidget设置隐藏标题栏,重叠时tab标签位置,自动填充满整个窗口
- 后盾网php多少钱_复合排水网价格多少钱
- 关于delete和delete[]
- python跟java 效率_Python与Java:哪个更好,如何选择?
- java 手势识别,AndroidStudio:手势识别
- Linux命令:find命令详解
- C# EntityFramework连接MySQL (DbFirst)
- 多功能计算机如何关闭,多功能的计算机显示终端
- Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理
- 公共代码参考(DisplayMetrics)
- AE Pixel Sorter 2 for Mac破解教程
- php毕设周记,毕设周记录如何写的
- 怎么有效的管理微信群?分享3点有用的经验
- 设计思维(Design Thinking)
- 发送ajax将浏览器卡死,jQuery Ajax同步参数致使浏览器假死怎么办
- K8s 之 ReadinessProbe(就绪探针)使用的迷惑
- 解决Python下安装unrar后仍然提示Couldn't find path to unrar library...
- JSP设置Excel表格换行_如何在WPS-Excel表格中设置可爱的“温馨提示”?
- Chrome浏览器运行超图三维场景
- 报错:npm ERR code EPERM
热门文章
- 学习Spring Boot:(十八)Spring Boot 中session共享
- Java 单例模式:懒加载(延迟加载)和即时加载
- JAVA分布式篇1——Linux
- springboot2稳定版本_重要版本Spring Boot 2.3.0发布 - spring.io
- 数控车椭圆编程实例带图_数控车床编程教程,图文实例详解
- php字符串中单引号与双引号的区别,简单概括PHP的字符串中单引号与双引号的区别...
- aqs clh java_【Java并发编程实战】----- AQS(一):简介
- mac os11以下安装Xcode
- python3中的 input函数_Python3中的input函数
- MySql主从同步最小配置