C++三大特性之继承

1、继承的概念及定义

>>继承是面向对象程序设计语言实现代码复用的一种手段,它允许你定义一个新类(派生类)对基类进行功能的拓展,类似于人类的遗传,派生类拥有基类的一部分(或全部)特性,也拥有自己的特性。

继承的定义格式:class 派生类名称 : 继承权限(public、protected、private) 基类名称

>>单继承:

class <派生类名>:<继承方式><基类名>

{

<派生类类体>

};

>> 多继承:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
<派生类类体>
};

2、继承权限&访问权限

>>继承权限:public > protected > private;  class 默认继承权限是private ,struct的默认继承权限是public

>>派生类继承基类除下的所有方法

  • 基类的构造函数、析构函数和拷贝构造函数。
  • 基类的重载运算符。
  • 基类的友元函数。

3、赋值兼容规则

>>在派生类中可以对派生类中属于基类的那部分(基类的对象、指针、引用)进行赋值

>>基类对象不能给派生类对象

>>基类的指针可以通过强制类型转换赋值给派生类的指针。但是必须是基类的指针是指向派生类对象时才是安全的

4、继承中的作用域

>>在继承体系中,基类和派生类拥有自己独立的作用域

>>若在派生类和基类中有同名成员,自雷将隐藏父类的对同名成员的访问,这种情况称为同名隐藏或者重定义,基类和派生类的成员函数只需要函数名相同就能构成同名隐藏

>>继承体系下尽量不要使用同名隐藏

#include <iostream>
#include <string>
using namespace std;

class person {
public:
	person(string name, int age, string gender,int id)
		: _name(name)
		, _age(age)
		, _gender(gender)
		, _id(id)
	{}
	void Print() {
		cout << "姓名:" << _name << endl;
		cout << "年龄:" << _age << endl;
		cout << "性别:" << _gender << endl;
		cout << "学号:" << _id << endl;
	}
public:
	string _name;  
	int _age;
	string _gender;
protected:
	int _id;   // 身份证号

};


class student : public person {
public:

	student(string name,int age, string gender, int id)
		: person::person(name,age,gender,id)
		, _id(id) 
	{}
	

protected:
	int _id;
};


int main() {
	person p1("jack", 20, "男", 110);
	p1.Print();
	student s1("xiaoming", 18, "男", 112);
	s1.Print();
	
	return 0;

}

5、派生类默认成员函数

>>派生类的构造函数、拷贝构造函数、赋值运算符重载必须先调用基类的完成基类自己的那部分的构造、拷贝初始化、赋值,然后再进行派生类自己的。

>> 派生类的再调用析构函数时,在清理完自己的资源之后会自动调用基类的析构函数清理属于基类的那部分资源

>>当基类中没有给出默认的构造函数,需要在派生类的初始化列表中 显示的给出基类的构造函数,用于完成属于基类自己的那部分成员的初始化

6、继承与友元、继承与static静态成员

>>友元关系不能被继承,即友元无法访问基类的私有成员与被保护成员

>> 如果基类中有被static修饰的成员,则在整个继承体系中只能出现一个这样的成员,无论派生出多少个派生类都只有一个这样的static成员

7、多继承中的菱形继承

>>菱形继承属于多继承的一种特殊情况,菱形继承由于第一个基类中的成员被继承了两次,所以会存在数据二义性问题,此时又需要虚拟菱形继承来解决菱形继承造成的数据二义性问题

>> 虚拟菱形继承发生在第一次继承

class person {
public:
	string _name;
};

class student : virtual public person {
public:
	int _id;   // 学号
};

class teacher : virtual public person {
public:
	int _num;   // 职工编号
};

class Assistant : public student, public teacher {
public:
	string _course;   // 课程
};

8、继承和组合


public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。

组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。 优先使用对象组合,而不是类继承 。

继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用 (white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的内部细节对子类可见 。 继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生类和基类间的依赖关 系很强,耦合度高。 对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对 象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse), 因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组合类之间没有很强的依赖关系, 耦合度低。优先使用对象组合有助于你保持每个类被封装。
          
组合的耦合度低,代码维护性好。不过继承也有用武之地的,有些关系就适 合继承那就用继承,另外要实现多态,也必须要继承。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值