继承

1.继承:是面向对象程序设计支持代码重用的重要机制,通过继承,可以在原有类的基础上派生出新类,新类将共享原有类的属性,并且可以增加新的特性
2.可以把继承过程看成是从一个类派生出一个新类的过程,派生出来的新类称为派生类或子类,而被继承的类称为基类或父类
3.一个基类可以派生出多个派生类,一个派生类也可以由多个基类派生而来
4.单继承:一个基类派生出一个派生类的过程
5.多继承:多个基类派生出一个派生类的过程
6.面向对象的继承与派生机制,最主要的目的是实现代码的重用和扩充
7.由基类派生新类的过程需要经历三个步骤
1)吸收基类成员:全盘接收基类成员,但构造函数和析构函数除外
2)改造基类成员:基类依靠继承方式改变成员的访问权限,同名覆盖,派生类成员覆盖基类成员
3)添加新成员:派生类添加新成员,使其功能扩展
单继承
class 派生类名:继承方式 基类名
{
 声明派生类新成员;
};
基类名:指明了派生类的基类,这个基类必须在声明派生类之前已经声明,否则会导致编译错误
8.继承方式:公有继承,私有继承,保护继承
公有继承:基类的public和protected被派生类继承过来,作为派生类的公有成员和保护成员,基类和派生类的公有成员都可以直接通过派生类的对象名来访问
----------------------------------------------------------------
class A//声明基类
{
 public:
  void setx(int a){x=a;}
  void sety(int b){y=b;}
  int getx() const{return x;}
  int gety() const{return y;}
 private:
  int y;
 protected:
  int x;
};
class B:public A //派生类声明
{
 public:
  int getsum(){return x+gety();}
  int c;
};
-----------------------------------------------------------
int main()
{
 B b;
 b.setx(2);//setx是从A类中继承过来的
 b.sety(3);
 cout<<"X= "<<b.getx()<<" Y= "<<b.gety()<<endl;
 cout<<"X+Y="<<b.getsum()<<endl;
}
-------------------------------------------------------
[root@localhost CPP]# ./s
X= 2 Y= 3
X+Y=5
-----------------------------------------------------
在派生类中可以直接访问从基类继承来的保护成员x,但是基类的么有成员y,只能通过接口函数访问
cout<<"sizeof(a) "<<sizeof(a)<<endl;
cout<<"sizeof(b) "<<sizeof(b)<<endl;
--------------------------------------
sizeof(a) 8  //对象a 类A的数据成员的大小为8
sizeof(b) 12 //对象 b 类B的数据成员的大小为4+A=12
--------------------------------------------------------------
私有继承:
基类的公有成员和保护成员被派生类继承过来,作为派生类的私有成员,而基类的私有成员在派生类中不能直接使用
-----------------------------------------------------------------------------------
class A//声明基类
{
 public:
  void setx(int a){x=a;}
  void sety(int b){y=b;}
  int getx() const{return x;}
  int gety() const{return y;}
 private:
  int y;
 protected:
  int x;
};
class B:private A //派生类声明,私有继承A
{
 public:
  void setBx(int a){setx(a);}
  void setBy(int b){sety(b);}
  int getBx(){return getx();}
  int getBy(){return gety();}
  int getsum(){return x+gety();}
  int c;
};
---------------------------------------------------------------------------------------------
int main()
{
 B b;
 b.setBx(10);//setx是从A类中继承过来的
 b.setBy(3);
 cout<<"X= "<<b.getBx()<<" Y= "<<b.getBy()<<endl;
 cout<<"X+Y="<<b.getsum()<<endl;
}
----------------------------------------------------------------
[root@localhost CPP]# ./s
X= 10 Y= 3
X+Y=1
---------------------------------------------------------
类B是由类A私有派生而来的,无法直接通过类B的对象访问A中的任一成员,只能通过成员函数访问
保护继承:基类的公有成员和保护成员被派生类继承过来,作为派生类的保护成员,而基类的私有成员在派生类中不能直接使用
9.在程序的任何部分如果声明一个类的对象,就可以通过这个对象访问对象所属类中的所有公有成员,但不能访问其私有和保护成员,而一个派生类的成员函数则可以访问所属类中的新声明的所有成员,以及派生它的基类中的公有和保护成员,类的私有成员只能被所属类的成员函数访问,在其它任何地方都不可见,即不可访问
10.派生类和基类都有相应的构造函数和析构函数
在创建派生类的对象时,系统首先调用其基类的构造函数来初始化从基类中继承的数据成员,然后调用派生类的构造函数初始化在派生类中新声明的数据成员,终止对象时,析构函数的执行顺序相反
[root@localhost CPP]# ./s
-----A constructor------//基类的构造函数
-----B constructor------
X= 10 Y= 3
X+Y=13
-----B destructor------
-----A destructor------
-------------------------------------------
11.基类的构造函数和析构函数是不能继承的,若基类没有构造函数,派生类也可以不定义构造函数,新增加的数据成员可以用成员函数来赋值,若基类有带参数的构造函数,派生类也必须定义带参数的构造函数,提供一个将参数传递给基类构造函数。
派生类构造函数执行顺序如下:
1)调用基类的构造函数,调用顺序与声明派生类时基类在声明语句中出现的顺序一致(先基类)
2)调用内嵌对象成员的构造函数,调用顺序是按照它们在派生类中的顺序(再客人)
3)调用派生类的构造函数(再自己)
派生类析构函数执行顺序:先自己-->再客人-->后基类
12.多继承:由多个基类派生出一个类的情形,可以看作是单继承的扩充
声明形式如下:
class 派生类名:继承类型1 基类名1,继承类型2 基类名2...
{
 声明派生类新成员;
};
每一个派生类型对应的是紧接其后给出的基类,而且必须给每个基类指定一种派生类型,如果没指定,相应的基类型则取私有派生类型,而不是和前一个基类取相同的派生类型
13.多继承可以看作是多个单继承的组合,单继承可以看作是多继承的特例。
14.在派生类中访问公共基类成员时,存在二义性问题
二义性问题:包括|成员函数的|二义性,多个基类中存在同名的成员函数或数据成员
                | 数据成员 |
15.解决二义性问题:通过在程序中指定想要访问的成员来消除二义性,这是可使用作用域运算符"::"指定成员所属的类,另一种是使用虚基类
16.面向对象编程的原则:
1)面向接口的编程,而非面向实现的编程
2)模块化编程,高内聚,低耦合
3)变化的模块用组全,不变的模块用继承

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值