第六章类的继承

基类和派生类

类的基本概念与语法


新的类从已有类那里得到已有的特性,称为类的继承
在已有类的基础上新增自己的特性而产生新类的过程称为类的派生


基类和派生类的概念


被继承的类称为基类(父类)
派生出的新类称为派生类(子类)
直接基类直接参与 派生出的某类的基类。
间接基类基类的基类 甚至更高层的基类


继承和派生的目的


继承的目的——代码重用
派生的目的——新的问题出现时,对原有的程序进行改造


 派生类定义的语法


class 派生类名: 继承方式 基类名1, 继承方式 基类名2,... 继承方式 基类名n
{
    派生类成员的声明;
}

单继承时派生类的举例

单继承:派生类只从一个直接基类继承
 

class Derived:public Base{
    public:
        Derived();
        ~Derived();//构造函数和析构函数都不能从基类继承
};
//派生类名:Derived 继承方式:public 基类名:Base
//还可以增加其他新增的数据成员和成员函数

单继承时,派生类得到了单个基类的特征

多继承时派生类的举例

多继承:派生类从多个直接基类继承

class Derived:public Base1,Private Base2{
    public:
        Derived();
        ~Derived();//构造函数和析构函数都不能从基类继承
};
//派生类:Derived 继承方式:public 基类名1 Base1, 继承方式:private Base2
//还可以增加其他新增的数据成员和成员函数

多继承时,派生类得到了多个基类的特征。

派生类的构成

  1. 吸收的基类成员——基类中除构造函数和析构函数之外的所有成员
  2. 改造过的基类成员——定义和某基类成员同名的成员,隐藏或覆盖了外层同名的成员
  3. 添加新的成员——使派生类在功能上有所发展

访问控制

类的继承方式

继承方式规定了如何访问从基类继承的成员。

不同继承方式的影响体现在:

  1. 派生类的内部派生类成员对基类成员的访问
  2. 派生类的外部,通过派生类对象对基类成员的访问

3种不同继承方式

  1. 公有继承(public)
  2. 私有继承(private)【默认继承方式,如果不显式指明继承发生,即表示继承方式为private】
  3. 保护继承(protected)

公有继承

公有继承是最常用的继承方式。

访问方式

基类的publicprotected成员:访问属性在派生类中保持不变

基类的private成员:不可以直接访问(仅可以通过基类的公有访问接口,即公有函数成员进行访问)

访问权限

派生类内部,比如派生类中的成员函数:可以直接访问基类中的publicprotected成员,但不能直接访问基类的private成员。

派生类的外部,通过派生类对象:只能访问其public成员

class Point{
	public:
		void initPoint(float x=0,float y=0){
			this->x=x;
			this->y=y;
		}
		void move(float offX,float offY){
			x+=offX;
			y+=offY;
		}
		float getX()const{
			return x;
		}
		float getY()const{
			return y;
		}
	private://基类的私有成员
		float x,y;
};
class Rectangle:public Point{
	public://新增公有函数成员
		void initRectangle(float x,float y,float w,float h){
			initPoint(x,y);//调用基类的公有函数访问基类的私有成员
			this->w=w;
			this->h=h;
		}
		float getH(){
			return h;
		}
		float getW(){
			return w;
		}
	private://新增的私有数据成员
		float w,h;
};
#include <iostream>
#include "Point.h"
#include "Rectangle.h"

using namespace std;

int main(){
	Rectangle rect;	
	rect.initRectangle(2,3,20,10);
	rect.move(3,2);
	cout<<"The data of rect(x,y,w,h):"<<endl;
	/*调用从基类继承来的getX(),getY()函数*/
	cout<<rect.getX()<<","<<rect.getY()<<","<<rect.getW()<<","<<rect.getH()<<endl;
	
	return 0;
}

如果在主函数中将

cout<<rect.getX()<<","<<rect.getY()<<","<<rect.getW()<<","<<rect.getH()<<endl;

改为

cout<<rect.x<<","<<rect.y<<","<<rect.getW()<<","<<rect.getH()<<endl;

编译器就会报错【我使用的是devC++】

 

 

原因是x,y是Point类的私有成员,派生类Rectangle无法直接访问

如果将Point类的x,y设为公有

class Point{
	public:
		void initPoint(float x=0,float y=0){
			this->x=x;
			this->y=y;
		}
		void move(float offX,float offY){
			x+=offX;
			y+=offY;
		}
		float getX()const{
			return x;
		}
		float getY()const{
			return y;
		}
		float x,y;//x,y设为公有成员
};

编译就可以通过

 

私有继承

最严格的一种继承方式

访问控制

基类的publicprotected成员:都以private身份出现在派生类中,基类的private成员:不可直接访问。(仅通过基类的公有访问接口,即公有成员函数进行访问)

访问权限

在派生类的内部,比如派生类中的成员函数中:可以直接访问基类中的public和protected成员,但不能直接访问基类中的private成员。

在派生类的外部,通过派生类的对象:不能直接访问从基类继承的任何成员(因为它们在基类中的访问控制都变为私有)

class Point{
	public:
		void initPoint(float x=0,float y=0){
			this->x=x;
			this->y=y;
		}
		void move(float offX,float offY){
			x+=offX;
			y+=offY;
		}
		float getX()const{
			return x;
		}
		float getY()const{
			return y;
		}
	private://基类的私有成员
		float x,y;
};
class Rectangle:private Point{//以私有方式继承
	public://新增公有函数成员
		void initRectangle(float x,float y,float w,float h){
			initPoint(x,y);//调用基类的公有函数访问基类的私有成员
			this->w=w;
			this->h=h;
		}
		float getH(){
			return h;
		}
		float getW(){
			return w;
		}
		//新的访问接口,公有,可类外调用
		/*重新定义之后变为派生类的公有成员*/
		void move(float offX,float offY){
			Point::move(offX,offY);
		}
		float getX()const{
			return Point::getX();
		}
		float getY()const{
			return Point::getY();
		}
	private://新增的私有数据成员
		float w,h;
};
#include <iostream>
#include "Point.h"
#include "Rectangle.h"

using namespace std;

int main(){
	Rectangle rect;
	rect.initRectangle(2,3,20,10);
	rect.move(3,2);
	cout<<"The data of rect(x,y,w,h):"<<endl;
	/*调用派生类成员函数的getX(),getY()*/
	cout<<rect.getX()<<","<<rect.getY()<<","<<rect.getW()<<","<<rect.getH()<<endl;
}

保护继承

访问控制

基类的publicprotected成员:都以protected身份出现在派生类中。

基类的private成员:不可直接访问(仅通过基类的公有访问接口,即公有成员函数进行访问)

访问权限

在派生类的内部 ,比如派生类中的成员函数中:可以直接访问基类中的publicprotected成员,但不能直接访问基类的private成员。

在派生类的外部,有可能访问从基类继承的publicprotected成员。(它们在派生类中的属性都是protected,可以在该派生类的子类中访问)

保护成员

特点

对建立其所在类对象的模块来说,它与私有成员的性质相同,不能通过对象名来访问

对其派生类来说,它与public对象相同,可以访问,

保护成员用在何种场合?

基类和派生类都是自己写的。

class A{
	protected:
		int x;//类A中的保护成员
};

int main(){
	A a;
	a.x=5;//错误,和类A的私有成员相同,不能在类A之外访问
}

 

 

class A{
	protected:
		int x;
};
class B:public A{
	public:
		void f();
};
void B::f(){
	x=5;//正确,类B是类A的派生类,可以在类B中访问类A的保护成员
}

多继承举例

#include <iostream>
using namespace std;

class A{
	public:
		void setA(int x){
			a=x;
		}
		void showA()const{
			cout<<a<<endl;
		}
	private:
		int a;
};
class B{
	public:
		void setB(int x){
			b=x;
		}
		void showB()const{
			cout<<b<<endl;
		}
	private:
		int b;
};
class C:public A,private B{
	public:
		void setC(int x,int y,int z){
			setA(x);
			setB(y);
			c=z;
		}
		void showC()const{
			cout<<c<<endl;
		}
	private:
		int c;
};

int main(){
	C obj;
	obj.setA(5);
	obj.showA();
	obj.setC(6,7,9);
	//obj.setB(6);//错误
	//obj.showB();//错误
	return 0;
}

对于注释的两行语句,因为是私有继承的,所以派生类无法访问,执行这两句就会报错。

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值