继承与派生——面向对象的程序 ——类 成员 对象

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一.概念:

类的继承:一个新类从已有的类那里获得已有的特征。
类的派生:从已有的类(父类)产生一个新的子类。

最简单的示例:
class Student
{
	public:
		void display()
		{
			cout<<"num:"<<num<<endl;
		}
	private:
		int num;
};
重新声明另一个类
class Student
{
	public:
		void display()
		{
			cout<<"num:"<<num<<endl;//此行原来已有
			cout<<"name:"<<name<<endl;
		}
	private:
		int num;//此行原来已有
		int name;
};

派生类是基类的具体化,而基类则是派生类的抽象。

二.派生类的声明方式

class 派生类名:【继承方式】 基类名
{
派生类新增的成员;
};

示例:根据根据前面已经声明的Student类基础上
单继承建立一个派生类Student1
class Student1:public Student
{public:
   void display_1()
   {cout<<"name:"<<name<<endl;}
 private:
    int name;
 };

继承方式:public(公用的),private(私有的),protected(受保护的)。不写此项默认为private。具体在后面会阐述。

三.派生类的构成

  1. 从基类接收成员。派生类把基类的全部成员(不包括构造函数和析构函数)接收过来,没有选择权。
  2. 调整从基类接收的成员。可以声明一个与基类成员同名的成员,就会覆盖同名成员。用这种方法可以用新成员取代基类的成员。
  3. 在声明派生类时增加的成员。

四.派生类成员的访问属性

公用继承public

继承方式为public。基类的公有成员和保护成员在派生类中保持原有的访问属性,其私有成员仍为基类所有,为派生类的不可访问成员。
只能通过基类的公用成员函数来引用基类的私有数据成员

私有继承private

基类的公有成员和保护成员在派生类中成了私有成员。私有基类的私有成员在派生类中成为不可访问成员。

保护成员和保护继承protected

保护基类的公有成员和保护成员在派生类都成了保护成员,私有成员依然为基类私有。

保护成员不能被类外访问,与私有成员相似,但是保护成员可以被派生类的成员函数引用。

  • 多级派生时的访问属性
    示例:A类是基类,类B是类A的派生类,类C是B类的派生类,则类C也是类A的派生类。B称为A的直接派生类,C是A的间接派生类。
    在多级派生的情况下,各成员的访问属性仍按以上原则确定。

五.派生类的构造函数和析构函数

(1)简单的派生类构造函数

派生类构造函数 一般形式:
派生类构造函数名(总参数表):基类构造函数名(参数表)
{派生类中新增数据成员初始化语句}

示例:定义构造派生类
public:
   Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)
   //因为在这里不是定义基类构造函数,而是调用基类构造函数,
   //因此这些参数是实参而不是形参
      {age=a;//在函数体中只对派生类新增的数据成员初始化
       addr=ad;}
  也可以改成一下方式:
  Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s),agg(a),addr(a){}

注:在函数体中只对派生类新增的数据成员初始化

(2)有子对象的派生类构造函数

一般形式:派生类构造函数名(总参数表):基类构造名(参数表),子对象名(参数表){派生类中新增数据成员初始化表}

示例:包含子对象的派生类的构造函数
(monitor班长是基类Student的对象,也是派生类Student1的子对象)
#include<iostream>
#include<cstring>
using namespace std;
class Student
{
	public:
		Student(int n,string nam)//基类构造函数
		{num=n;name=nam;}
		void display()//成员函数,输出基类数据成员
		{cout<<"num:"<<num<<endl<<"name:"<<name<<endl;}
	private:
		int num;
		string name;
 } ;
class Student1:public Student//声明公用派生类Students1
{
	public:
		Student1(int n,string nam,int n1,string nam1,int a,string ad)
		:Student(n,nam),monitor(n1,nam1)//派生类构造函数
		{
		    age=a;addr=a;	
		}
	void show()
	   {
	   	cout<<"this student is"<<endl;
	   	display();
	   	cout<<"age"<<age<<endl;
	   	cout<<"address"<<addr<<endl;
	   }
	void show_monitor()
	{
		cout<<endl<<"class monitor is"<<endl;
		monitor.display();//调用基类成员函数
	}
	private:
		Student monitor;//定义子对象(班长)
		int age;
		string addr;
};
int main()
{
	Student1 stud1(10010,"wang",10011,"li",19,"beingjing");
	stud1.show();//输出学生数据
	stud1.show_monitor() ;//输出子对象数据
	return 0;
}
(3)多层派生时的构造函数**

基类构造函数首部:

student(int n,string nam)

派生类student1的构造函数首部:

student(int n,string nam,int a):studen(n,nam)

派生类student2的构造函数首部:

student(int n,string nam,int a,int s):student1(n,nam,a)

注:每一层派生类只需要写出上一层派生类的构造函数即可。

  • 4)派生类构造函数的特殊形式
    当不需要对派生类新增成员进行任何操作时,函数体可以为空,即构造函数是空的。
示例:将上面的代码改写
student1(int n,string nam,int n1,string nam1)
:student(n,nam),monitor(n1,nam1){}

六.多重继承

多重继承:允许一个派生类同时继承多个基类

(1)声明多重继承的方法
classD:public A,private B,protected C
        {类D新增加的成员}
(2)多重继承派生类的构造函数**

派生类构造函数名(总参数表):基类1构造函数(参数表),基类2构造函数(参数表),基类3构造函数(参数表列)
{派生类中新增数据成员初始化语句}

(3)虚基类

使得在继承间接共同基类时只保留一份成员。避免产生二义性(多重继承引起的),使其唯一地标识一个成员。
一般形式:class 派生类名:virtual 继承方式 基类名

class A{...};
class B:virtual public A{...};//声明类B是类A的公用派生类,A是B的虚基类

虚基类的初始化

class A//定义基类A
{A(int i){}...};//基类构造函数,有一个参数

class B:virtual public A//A作为B的虚基类
{B(int n):A(n){}...};//B类构造函数,在初始化表中对虚基类初始化

class C:virtual public A
{C(int n):A(n){}...};

class D:public B,public C//D类构造函数,在 初始化表中对所有基类初始化
{D(int n):A(n),B(n),C(n){}...};

注:在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。

七.基类与派生类的转换

基类与派生类对象之间有赋值兼容性
--------即可以用子类(公用派生类)对象对其基类对象赋值

示例:
A a1;//定义基类A对象a1
B b1;//定义类A的公用派生类B的对象b1
a1=b1;

注:(1)只能用子类对象对其基类对象赋值,同一基类的不同派生类对象之间也不能赋值。
(2)派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化。
(3)如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象。
(4)指向基类对象的指针变量也可以指向派生类对象。

ps:详情有空再加一点。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值