1.继承与多肽-基础入门

原创 2016年05月31日 11:17:09

从本篇文章开始将要讲解C++里面最重要的内容:继承与多肽。为什么要把继承和多肽放在一块讲是因为多肽只能发生在父类和子类之间(也就是没有继承就没有多肽)。

 

继承与多肽我准备花费三个篇幅来讲解:

1.继承与多肽-基础入门

2.继承与多肽-项目实战

3.继承与多肽-实现原理

 

关于上面的三个篇幅我将采用三篇文章来讲解,今天这篇文章先讲解.继承与多肽的基础入门篇。

 

基础入门篇我主要是先讲解下和多肽有关的几个核心概念:函数重写、赋值兼容性原则、多肽

1.函数重写

说到函数重写大多数人肯定会和函数重载相混淆,如果有混淆的请看我的 “函数重载和函数重写的本质区别” 。函数重写就是子类定义了和父类一模一样的成员函数(包括参数个数、参数顺序、返回值都一模一样),函数体可以不一样。例如下面的代码:

#include <iostream>

using namespace std;

class Parent
{
protected:
	int nMoney;

public:
	// 父类构造函数 
	Parent()
	{
		nMoney = 10;
	}

	// 老爸炫富方法
	void showMoney()
	{
		cout << "Parent::showMoney() = " << nMoney << endl;
	}
};

class Child : public Parent
{
protected:
	int nMoney;
public:
	// 子类的构造函数
	Child()
	{
		nMoney = 100;	
	}
	// 孩子也有炫富的方法 和老爸一模一样 只是孩子挣的钱比较多了 老爸10万 孩子是老爸的十倍
	void showMoney()
	{
		cout << "Child::showMoney() = " << nMoney << endl;
	}	
}; 

int main()
{
	Child c;
	c.showMoney();

	return 0;
}

程序运行结果:Child::showMoney() = 100

我们可以看到父类和子类都有相同的属性 int nMoney(只是老爸是10万,而孩子却又100万),并且还有相同的炫富方法void showMoney()。上一节我们已经说过当父类和子类有相同的成员变量时,默认(在不适应作用于分辨符的情况)会访问子类那个。其实如果父类和子类有相同的成员函数,虽然父类的那个成员函数已经继承给子类,但是在用子类的对象去调用这个成员函数时,默认还是会使用子类的那个重写函数,也就是我们的c.showMeney()为什么会打印 Child::showMoney() = 100的原因,因为默认是使用子类的成员变量、子类的成员函数。这个在子类和父类都有的showMoney()函数,就是函数重写。简单的说,函数重写就是定义了一个和父类一样的函数,为了下面方便理解,我讲的比较多。

2.赋值兼容性原则

赋值兼容性原则概念:子类的对象可以当做父类使用。

赋值兼容性原则就是父类的指针和引用可以操作子类的对象,这一句话看似很简单,但是真的要是可以灵活用到你的工程上,你的工程将会变得非常容易管理。例如根据上面的代码我们在main函数中有如下定义:

 Child c1;

 Child c2;

 Parent *p1 = &c1;

 Parent &p2 = c2;

 

C++中什么样的指针或者引用必须指向什么样的对象,但是由于赋值兼容性原则,子类可以当做父类使用,所以一个父类的指针可以指向子类的对象,因为编译器会把子类当做父类。假设一下,如果编译器把c1和c2当做Child类型的对象,程序必然会报错,因为一个Parent指针指向了一个不是Parent类型的对象。所以编译器在这里是把c1和c2当做Parent类型的对象。这就是我们平时说的赋值兼容性原则。为了验证上面所说的,我们来看一个程序:

#include <iostream>

using namespace std;

class Parent
{
protected:
	int nMoney;

public:
	// 父类构造函数 
	Parent()
	{
		nMoney = 10;
	}

	// 老爸炫富方法
	void showMoney()
	{
		cout << "Parent::showMoney() = " << nMoney << endl;
	}
};

class Child : public Parent
{
protected:
	int nMoney;
public:
	// 子类的构造函数
	Child()
	{
		nMoney = 100;	
	}
	// 孩子也有炫富的方法 和老爸一模一样 只是孩子挣的钱比较多了 老爸10万 孩子是老爸的十倍
	void showMoney()
	{
		cout << "Child::showMoney() = " << nMoney << endl;
	}	
}; 

int main()
{
	Child c1;
	Child c2;
	Parent *p1 = &c1;  // 父类的指针指向子类的对象1
	Parent &p2 = c2;   // 父类的引用指向子类的对象2

	p1->showMoney();
	p2.showMoney();
	return 0;
}

程序输出结果:

Parent::showMoney() = 10
Parent::showMoney() = 10

疑问:

Parent *p1 = &c1;  这句代码明明是引用了c1,为什么还是调用了父类的炫富函数?

Parent &p2 = c2;   这句代码明明值指向了c2,为什么还是调用了父类的炫富函数?

 

答案:这个就是复制兼容性原则在搞鬼,因为编译器会把c1和c2当做父类的对象,所以当然会去使用父类的炫富函数。这个往往不是我们需要的,我们需要的往往是指向子类对象就使用子类的函数,指向父类对象就使用父类的函数。这样哦我们呢就可以引出多肽的概念了。

 

3.多肽:多肽就是一个调用语句可以实现多种状态。

下面我把上面的代码实现多肽,再看看运行结果,大家就可以理解多肽是个什么样的东西了。

#include <iostream>

using namespace std;

class Parent
{
protected:
	int nMoney;

public:
	// 父类构造函数 
	Parent()
	{
		nMoney = 10;
	}

	// 老爸炫富方法, 使用 virtual 关键字可以实现多台机制
	virtual void showMoney()
	{
		cout << "Parent::showMoney() = " << nMoney << endl;
	}
};

class Child : public Parent
{
protected:
	int nMoney;
public:
	// 子类的构造函数
	Child(int money)
	{
		nMoney = money;	
	}
	// 孩子也有炫富的方法和老爸一模一样 只是孩子挣的钱比较多了 老爸10万 孩子是老爸的十倍
	// 这里的关键字不使用也可以,因为当父类中使用了virtual,子类重写的函数自动的也会变成虚函数
	virtual void showMoney()
	{
		cout << "Child::showMoney() = " << nMoney << endl;
	}	
}; 

int main()
{
	Child  child1(10);  // 定义了一个 Child 类型的对象 child1,炫富值:10
	Child  child2(20);  // 定义了一个 Child 类型的对象 child2,炫富值:20
	Parent parent;      // 定义了一个 Parent 类型的对象 parent,炫富值:10
	Parent * p1;        // 定义了一个父类的指针,用来操作父类和子类对象使用

	p1 = &child1;       // 指向child1
	p1->showMoney();

	p1 = &child2;       // 指向child2
	p1->showMoney();  

	p1 = &parent;       // 指向parent
	p1->showMoney();  


	return 0;
}

程序运行结果:

Child::showMoney() = 10
Child::showMoney() = 20
Parent::showMoney() = 10

看似不起眼的结果背后却蕴藏了一个程序设计中非常常用的设计方法,下面我先讲解下这段代码。

大家有没有发现两个类除了子类的构造函数发生变化以外还有什么发生了变化?父类中被重写的函数加了一个 virtual 关键字,子类重写的那个函数也加了关键字 virtual 。这样就可以实现我们所说的多肽。mian函数里面定义了两个子类对象,炫富值分别是10和20,并且定义了一个父类的对象和指针。

我们可以发现虽然使用了同样调用语句p1->showMoney(),却产生了不同的结果,这就是上面说的一个调用语句可以实现多种状态。

 

到这里多肽已经讲完,总结下要实现多肽所必须的几个条件:

1.多肽是发生在父类和子类之间的,单一的一个类不可能实现多肽。

2.父类和子类必须发生重写函数,并且父类被重写的函数前面必须用 virtual 关键字进行修饰。

3.在使用多肽特性时,必须定义一个父类的指针或者引用。(这个在下一节 “继承与多肽-项目实战” 会详细讲解为什么要这样做)

 

在进入下一节之前,我们可以思考一个问题:

现在有一个父类P1,有50个子类 C1-C50继承了它,这50个子类中都重写了父类P1的某个函数(比如说showMoney()函数),50个子类每个子类都有对应的一个对象,总共也就是50个不同类型对象,现在要对这50个不同类型的对象全体炫富一次用程序怎么实现?

说明:我们上面的例子只是一个子类,用这个子类定义了两个同类型的对象,而上面问题说的是50个子类,每个子类定义1个对象,然后对每个对象炫下富。

 

下一节我们会用一个比较典型的小项目来深入讲解怎么在工程里面巧妙的使用多肽并且解决上面的问题。

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

1.继承与多肽-基础入门

从本篇文章开始将要讲解C++里面最重要的内容:继承与多肽。为什么要把继承和多肽放在一块讲是因为多肽只能发生在父类和子类之间(也就是没有继承就没有多肽)。   继承与多肽我准备花费三个篇幅来讲解: 1....
  • weiaipan1314
  • weiaipan1314
  • 2016年05月31日 11:17
  • 904

继承、多态

  • 2013年03月23日 13:57
  • 930B
  • 下载

java之继承,封装,多肽

一,封装 理解:把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能的隐藏对象内部实现细节 例如:我们写一个简单的输入两个数和一个操作符(+,-,*,/)的的运算, 可以把具体操作和属性封装成一...
  • qq_28055429
  • qq_28055429
  • 2016年04月16日 21:42
  • 1493

Java封装、继承和多态

前言:假如生活欺骗了你,
  • wu371894545
  • wu371894545
  • 2016年11月24日 10:19
  • 11461

C# 多肽

封装、继承、多态,面向对象的三大特性,前两项理解相对容易,但要理解多态,特别是深入的了解,对于初学者而言可能就会有一定困难了。我一直认为学习OO的最好方法就是结合实践,封装、继承在实际工作中的应用随处...
  • c394865392
  • c394865392
  • 2016年08月24日 10:17
  • 296

继承和多态

在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Supe...
  • cabbage2008
  • cabbage2008
  • 2016年05月03日 10:40
  • 157

继承与多态的区别

1、  什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为。 特点:在继承关系中,父类更通用、子类更具体。父...
  • o9109003234
  • o9109003234
  • 2013年11月24日 13:01
  • 12094

重拾java基础(八):继承、多肽总结

一、继承 1、在java编程中会遇到两个或者多个类中存在多个代码重复,这时我们就需要在这 两个或多个类中寻找他们的共同特点,然后寻找一个大的类别来包括,他们的共 同属性和方法,这...
  • huangxiaoguo1
  • huangxiaoguo1
  • 2017年01月14日 23:18
  • 453

继承与多态

继承: (1)把多个类中的相同的属性和行为进行抽取,封装到一个类中,   然后再建立新类的时候,不需要从头做起,继承刚才定义的那个类即可。 (2)好处: A:提高代码的复用性。 B:让类与类之间产生了...
  • lixin412524
  • lixin412524
  • 2014年08月05日 11:28
  • 166

继承和多态

1 泛化泛化是一般元素和特殊元素之间的关系,是将多个特殊元素中的公共特征或行为提取出来而形成一般元素。可替换性原则是,在使用一般元素的任何地方都可以使用特殊元素来代替,因为特殊元素除了拥有自身所有的特...
  • peacefulsword
  • peacefulsword
  • 2006年07月30日 08:49
  • 568
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:1.继承与多肽-基础入门
举报原因:
原因补充:

(最多只允许输入30个字)