14.7 子类、调用顺序、访问等级与函数遮蔽

一:派生类概念
类之间有一种层次关系,有父类,有孩子类。比如车这个类,当成父类(也叫基类,超类),派生出卡车,轿车,他们属于孩子类(子类/派生类)

继承:有父亲类,有孩子类,构成了层次关系。继承这种概念,是面向对象程序设计的核心思想之一。
这种继承,就是我们要先定义一个父类。父类中定义一些公用的成员变量,成员函数。我们通过继承父类来构建新的类:子类。所以写代码时,只需写和子类相关的一些内容即可。子类一般会比父类更加庞大。

Human.h

#pragma once
#ifndef __HUMAN__
#define __HUMAN__
#include <iostream>
using namespace std;

class Human
{
public:
	Human();
	Human(int i);
public:
	int m_Age;
	char m_Name[100];
	void funcPub() {};
	void samenamefunc();
	void samenamefunc(int i);
	string samenamefunc(string s);
protected:
	int m_pro1;
	void funcPro() {};
private:
	int m_priv1;
	void funcPriv() {};
};
#endif // !__HUMAN__

Human.cpp

#include "Human.h"

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

Human::Human(int age)
{
	cout << "Human::Human(int age)" << endl;
}

void Human::samenamefunc()
{
	cout << "Human::samenamefunc()" << endl;
}

void Human::samenamefunc(int i)
{
	cout << "void Human::samenamefunc(int i)" << endl;
}

string Human::samenamefunc(string s)
{
	cout << "string Human::samenamefunc(string s)" << endl;
	return s;
}

Men.h

#pragma once
#ifndef __MEN__
#define __MEN__
#include "Human.h"

class Men:private Human
{
public:
	Men();
	using Human::samenamefunc;
public:
	void samenamefunc();
};


#endif // !__MEN__

Men.cpp

#include "Men.h"

Men::Men()
{
	cout << "Men::Men()" << endl;
}
void Men::samenamefunc()
{
	cout << "Men::samenamefunc()" << endl;
	//Human::samenamefunc();
	//Human::samenamefunc(100);
}

Test.cpp

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

int main()
{
	Men men;
	men.samenamefunc();
	men.samenamefunc(100);
	cin.get();
	return 0;
}

class Men :public Human。
class 子类名 : 继承方式,父类名
继承方式(访问等级/访问权限):public/protected/private;

二:派生类对象定义时调用构造函数的顺序

Men men;

父子类初始化谁先调用?当定义子类对象时,调用父类和子类的构造函数,且父类的构造函数体先执行,子类的构造函数体后执行。

三:public、protected、private

总结一下:三种访问权限

public:可以被任意实体所访问。
protected:只允许本类或者子类的成员函数来访问。
private:只允许本类的成员函数访问。

三种继承访问:
public 继承
protected 继承
private 继承

基类中的访问权限子类继承基类的继承方式子类得到的访问权限
publicpublicpublic
protectedpublicprotected
publicpublicpublic
protectedpublicprotected
privatepublic子类无权访问
publicprotectedprotected
protectedprotectedprotected
privateprotected子类无权访问
publicprivateprivate
protectedprivateprivate
privateprivate子类无权访问

总结:

<1>子类public继承父类不改变父类的访问权限。
<2>protected继承将父类中public成员变为子类的protected成员。
<3>private继承使得父类所有成员在子类中的访问权限变为private。
<4>父类中的private成员不受继承方式的影响,子类永远无权访问。
<5>对于父类来讲,尤其是父类的成员函数,如果你不想让外边访问,就设置为private; 如果你想让自己的子类能够访问,就设置为protected,如果你想公开,就设置为public。

四、函数遮蔽

子类中如果有一个同名函数,那么父类中,不管有几个同名函数(不管是否带参数),子类中都无法访问到。
如果我们确实想调用父类中的同名函数怎么办?
<1>在子类的成员函数中,用父类 "父类::函数名"强制调用父类函数。

void Men::samenamefunc()
{
	cout << "Men::samenamefunc()" << endl;
	Human::samenamefunc();
	Human::samenamefunc(100);
}

<2>using : using namespace
在 using c++11 中让父类同名函数在子类中可见。
通过 using 这个关键字,让父类的同名函数在子类中可见(让父类同名函数在子类中一重载的方式来使用)
说明:
<2.1>using Human::samenamefunc; 只能指定函数名,则凡是基类中public、protected的samenamefunc(基类中private不行)在子类中都可见。无法让一部分可见(函数重载全部可见)
<2.2>using 引入的主要目的是用来实现在子类中调用父类的重载版本。该函数在父类中的参数跟子类中的参数个数、类型不同。
Men men;
men.samenamefuc(12); 执行结果:执行了子类public::samenamefuc(int)的函数
men.samenamefuc();

class Men:private Human
{
public:
	Men();
	using Human::samenamefunc;
public:
	void samenamefunc();
};

注:
若使用“using Human::samenamefunc;”语句:
<1>using的基类方法不能有private重载,就算子类已重写的方法也不行,否则会报错。 >“Human”: 并非所有的重载都可访问
<2>使用“using Human::samenamefunc;”语句后,调用父类,可以使public、protected、private均不报错。但必须要有调用父类。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值