c++:继承(1)

继承:

1.何为继承:

继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。

2.继承的分类:

  • 单继承
  • 多继承

3.继承的方式:

  • public:公有继承
  • private:私有继承
  • protected:保护继承

4.继承的使用方式:

用extends关键字来继承父类。

如上面A类与B类,当写继承语句时, class A类 extends B类{ } 其中A类是子类,B类是父类。

5.继承的注意事项:

       1、子类拥有父类的特征,而父类没有,父类更通用,子类更具体,(特征包括属性和方法,自身的特性,拥有父类没有的)
  2、使用extends继承父类,语句格式:class 子类名 extends 父类名{}
  3、父类中一般只定义一般属性和方法(这个一般可以理解为是子类共有的,这就是父类更通用,而子类拥有其他的,所以子类更具体)
  4、子类中通过super关键字来调用父构造方法
  5、在子类中可以继承父类得那些东西,哪些不可以继承
  父类中public,protected修饰的属性,方法可以继承,private修饰的属性和方法不能被继承
  6、规则: 创建子类对象的时候,首先调用的是父类的无参构造方法创建一个父类对象
  7、可以在子类中显示调用父类的有参构造方法
  8、如果父类的属性均为private修饰,则可以通过共有的getter,setter方法来调用

有些编程语言支持多重继承,即一个子类别可以同时有多个父类别,比如C++编程语言;而在有些编程语言中,一个子类别只能继承自一个父类别,比如Java编程语言,这时可以利用接口来实现与多重继承相似的效果。

现今面向对象程式设计技巧中,继承并非以继承类别的“行为”为主,而是继承类别的“型态”,使得元件的型态一致。另外在设计模式中提到一个守则,“多用合成,少用继承”,此守则也是用来处理继承无法在执行期动态扩充行为的遗憾。

 


单继承:

单继承的格式:

class<派生类名>:<继承方式><基类名>
{
	<派生类新定义成员>
};
// 注意:继承方式不显式声明,则默认为私有继承

实例:

class A // 基类
{
......
};

class B:public A  //B为派生类:公有继承
{
......
};

class B2:protected A // 派生类2:保护继承
{
......
};

class B3:private A	// 派生类3:私有继承
{
......
};

//上面的代码中,B,B2,B3都继承自Base基类
//区别就是继承方式不同


多继承:

多继承的格式:

class<派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
    <派生类新定义成员>
};

实例:

class A1 // 基类1
{
....
};

class A2 // 基类2
{
....
};

class B1 :public A1, public A2 //B1 公有继承 基类1、2
{
....
};

class C2 :public A1, A2 // C2 公有继承 基类1,私有继承基类2
{
....
};

注意:

  • 注意,在多继承时,如果省略继承方式,默认为private
  • 多继承中派生类的模型与继承列表类的顺序是有关的

c++继承的访限定:

公有继承 : public

基类的public成员,在派生类中为共有属性,外部可以访问
基类的protect成员,在派生类中为保护属性,派生类可访问,外部不可访问
基类的private成员,可被派生类继承,但是派生类不可访问,当然外部也不可访问(体现了C++的封装隐藏特性)


保护继承 : protected

基类的public成员,在派生类中为保护属性,派生类可访问,外部不可访问
基类的protect成员,在派生类中为保护属性,派生类可访问,外部不可访问
基类的private成员,可被派生类继承,但是派生类不可访问,外部不可访问

私有继承 : private

基类的public成员,在派生类中为私有属性,派生类可访问,外部不可访问
基类的protect成员,在派生类中为私有属性,派生类可访问,外部不可访问
基类的private成员,可被派生类继承,但是派生类不可访问,外部不可访问

 

注意:

(1)基类成员在派生类中的访问权限不得高于继承方式中指定的权限

(2)不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。

(3)如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些。不希望在派生类中使用的成员才声明为 private。
(4)如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。
私有成员体现了数据的封装性,如果基类的私有成员可以被派生类所访问,即破坏了基类的封装性,这就会失去C++的一个重要特性。
(5)保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。

 


友元函数、静态成员函数的继承

友元函数不能被继承友元只是能访问指定类的私有和保护成员的自定义函数,不是被指定类的成员自然不能继承。

 

使用友元类应该注意:

(1)友元关系不能被继承。
(2)友元关系是单向的,不具有交换性。
(3)友元关系不具有传递性。

(4)友元可以访问类的私有成员。
(5)友元只能出现在类定义内部,友元声明可以在类中的任何地方,一般放在类定义的开始或结尾。
(6)友元可以是普通的非成员函数,或在之前定义的其他类的成员函数,或整个类。
(7)类必须将重载函数集中每一个希望设为友元的函数都声明为友元。
(8)友元关系不能继承,基类的友元对派生类的成员没有特殊的访问权限。如果基类被授予友元关系,则只有基类具有特殊 的访问权限。该基类的派生类不能访问授予友元关系的类。

 

 

下面代码解释静态成员和静态成员函数是否是可以继承的:

class Base
{
public:
	Base(int a = 0) :ma(a) {}

	static void function() // 定义Base类的静态成员函数
	{
		cout << "static function" << endl;
	}

	/* 修改mb的值,并打印其地址 */
	void BaseAdd()
	{
		mb *= 2;
		cout << "&mb = " << &mb << endl;
	}

	static int mb;
private:
	int ma;
};

// 静态成员变量类外初始化
int Base::mb= 10; 

class Derive : public Base
{
public:
	Derive(int data = 0) :Base(data), mc(data) {}

	/* 修改mb的值,并打印其地址 */
	void DeriveAdd()
	{
		mb *= 2;
		cout << "&mb = " << &mb << endl;
		cout << "mb = " << mb << endl;
	}

private:
	int mc;
};

int main()
{
	Derive d; // 定义派生类对象
	d.function(); // 调用基类静态成员函数
	d.BaseAdd();
	d.DeriveAdd();
	return 0;
}

注:基类的static变量和函数在派生类中依然可用,但是受访问性控制(比如,基类的private域中的就不可访问)。
对static变量来说,派生类和基类中的static变量是共用空间的,这点在利用static变量进行引用计数的时候要特别注意。
派生类的friend函数可以访问派生类本身的一切变量,包括从基类继承下来的protected域中的变量。但是对基类来说,它并不是friend的。

兼容性规则:

只能从下到上,不能从上到下(派生类->基类,不能基类到派生类)

 

1、派生类的对象可以赋值给基类的对象。

Base base;
Derive derive;

base = derive;//可以,派生类对象赋值给基类对象(下到上)
derive = base;//不可以,基类对象不能赋值给派生类对象(上到下)


2、派生类对象的地址可以赋值给其基类的指针变量

Base base;
Derive derive;

Base* base1 = &derive;//可以,派生类对象的地址赋值给基类类型的指针 (下到上)
Derive* derive1 = &base;//不可以 基类对象地址赋值给派生类类型的指针 (上到下)

3、派生类对象可以初始化基类的引用

Base base;
Derive derive;

Base& base2 = derive;//可以,派生类对象初始化基类的引用 (下到上)
Derive& derive2 = base;//不可以,不允许使用基类对象来初始化派生类的引用 (上到下)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值