c++初级 之 c++的继承性

c++的继承性就是指子类(派生类)继承父类(基类)。以下为例:

Person类

Person.h

#ifndef PERSON_H
#define PERSON_H

#include<string>
using namespace std;


class Person
{
public:     //类内不写关键字,默认是private成员
	Person();
	void eat();
	virtual~Person();//virtual关键字只用在.h中写就可以了。而且是被继承的,父类是虚的,子类不加virtual也会默认为是虚的,但为清楚保险,都加上virtual

private:
	string m_sName;
protected:
	int m_iAge;

};

#endif 

Person.cpp


#include<iostream>
#include"Person.h"
using namespace std;

Person::Person()
{
	cout << "Person()" << endl;
}


void Person::eat()
{
	cout << "Person::eat()" << endl;
}

Person::~Person()
{
	cout << "~Person()" << endl;
}

Worker.h


#ifndef WORKER_H//为了防止重复编译,在.h文件中采用这样的宏命令
#define WORKER_H

#include"Person.h"

class Worker:Person//不加关键字就默认是私有继承
{
public:
	void work();
	Worker();
	int m_iSalary;
	~Worker();

};

#endif

Worker.cpp


#include<iostream>
#include"Worker.h"
using namespace std;

Worker::Worker()
{
	cout << "Worker()" << endl;
}

void Worker::work()
{
	cout << "Worker::work()" << endl;
	//m_sName = "zxb";//子类不可访问父类的私有成员
	eat();//可以访问从父类的公有成员继承来的私有成员
	m_iAge ++;  //可以访问从父类的保护成员继承来的私有成员(实质是把父类的公有和保护成员都继承过来成了子类私有成员,这就是has a的关系,子类有父类的成员)
	m_iSalary = 9;
}

Worker::~Worker()
{
	cout << "~Worker()" << endl;
}

Soldier.h


#ifndef SOLDIER_H
#define SOLDIER_H
#include"Person.h"
class Soldier:protected Person//保护继承
{
public:
	void work();
	Soldier();
	~Soldier();
private:
	int m_iBonus;
	

};

#endif

Soldier.cpp


#include<iostream>
#include"Soldier.h"
using namespace std;

void Soldier::work()
{
	m_iBonus = 10;
	m_iAge = 20;//父类保护成员可以被访问
	//m_sName = "aa"; //父类的私有成员被继承到无法访问的位置
	cout << "Soldier::work()" << endl;
}
Soldier::Soldier()
{
	cout << "Soldier()" << endl;
}

Soldier::~Soldier()
{
	cout << "~Soldier()" << endl;
}	

Infantry.h


#ifndef INFANTRY_H
#define INFANTRY_H
#include"Soldier.h"


class Infantry:public Soldier//公有继承:将父类的公有成员和保护成员分别继承到自己的公有成员中,父类的私有成员继承到看不见的位置而且不可访问
{
public:
	Infantry();
	~Infantry();
	void attack();
	void work();

};

#endif

Infantry.cpp


#include<iostream>
#include"Infantry.h"
using namespace std;

Infantry::Infantry()
{
	cout << "Infantry()" << endl;
}

Infantry::~Infantry()
{
	cout << "~Infantry()" << endl;
}

void Infantry::attack()
{
	Soldier::work();//继承了父类的公有成员
	//m_iBonus = 20;//不能访问父类私有成员
	m_iAge = 22;//继承了父类的保护成员(是从曾父类继承来的保护成员)
}

void Infantry::work()
{
	cout << "Infantry::work()" << endl;
}

demo.cpp


#include<iostream>
#include<stdlib.h>
#include"Person.h"
#include"Worker.h"
#include"Infantry.h"
#include"Soldier.h"
using namespace std;

int main()
{
	Worker w1;//私有继承
	//w1.m_sName = "zxb";//父类私有成员在子类内部和类外均不可访问
	//w1.m_iAge = 22;//从父类的保护成员继承成的私有成员不可在类外访问
	w1.m_iSalary = 100000;//子类的公有成员可以在类外被访问
	//w1.eat();//从父类的公有成员继承成的私有成员不可在类外访问
	w1.work();//虽然Worker::work()函数定义里面包含了私有成员,但是work()是公有的啊!所以可以调用。这就是对私有成员或保护成员的间接访问方式
	Soldier s1;//保护继承
	//s1.eat();//从父类的公有成员继承成的保护成员不可在类外访问
	//s1.m_iBonus = 7;//不可访问私有成员
	s1.work();//可以访问公有成员
	Infantry i1;//公有继承
	i1.attack();//attack()里调用了从父类公有成员继承来的Soldier::work()
	i1.work();//此时访问的是子类自己的公有成员work(),这就是子类的work()隐藏了从父类继承的Soldier::work()。
	i1.Soldier::work();//此时访问的是继承来的公有成员

	Soldier s2 = i1;//这样
	//s2 = i1;//或这样都是可以的,因为步兵Infantry一定是Soldier,子类一定是父类的一种,是is a的关系。但是注意只是内容一样,实质是不一样的两块内存,地址也不同
	//Infantry i2 = s1;//反过来就不行了
	Soldier* p1 = &i1;//用指针也可以
	p1->work();

	
	system("pause");
	return 0;

}

运行结果:



A.继承有公有继承、私有继承、保护继承:

三种方式中,“无法访问”不代表子类没有继承父类的私有成员,而是将父类的私有成员继承到了无法访问的位置,无法直接访问,但是可以通过继承的其他可以访问的成员间接访问。

B.继承有多重继承(如上例的Person->Worker->Soldier),有多继承(指一个子类继承了多个父类;一般不太好用)。

C.子类和父类的两种关系:1.has a 指子类 有 父类的所有成员2.is a 指子类 是 一种父类。

D.继承里的隐藏关系:子类和父类的成员会存在隐藏关系,比如程序里的父类Soldier::work()和子类Infantry::work(),子类Infantry里既有自己的work()也有继承来的父类的work()而且都是公有成员。如程序里的i1,直接调用work()时,会调用到自己的work(),而父类的work()就好像被子类自己的work()隐藏起来了似的,如果要调用父类的work(),就要写明是Soldier::work()。

E.虚函数、多态和覆盖关系的必要性:如程序里的p1,虽然指向了i1,但是调用work()时,依旧调用到了自己(父类)的work(),因为p1的类型是父类指针Soldier*,所以直接调用肯定会调用到父类的函数,不可能调用到子类的函数。那有什么办法可以让p1调用work()时调用到子类对象i1的work()吗?这就需要用到虚函数、多态,涉及覆盖的关系了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值