继承、多态

常用的继承有三种:公有继承、保护继承、私有继承

公有继承

1 运用protected声明类的属性时,只允许友元类和派生类访问它,禁止在类外部通过实例对象访问。
下面用一个例子解释公有继承的应用以及protected访问限定符的作用

#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
class fish
{
protected :
	bool Freshwaterproperty;
public:
	void swim()
	{
		if (Freshwaterproperty == true)
			cout << "the fish  is in lake " << endl;
		else
			cout << "the fish is in sea" << endl;
	}
};
class seafish:public fish
{
public:
	seafish()
	{
		Freshwaterproperty =true;
	}
};
class lakefish :public fish
{
public:
	lakefish()
	{
		Freshwaterproperty =false;
	}
};
int main()
{
	seafish lunch;
	lunch.swim();
	lakefish dinner;
	dinner.swim();
    return 0;
}

2 基类的初始化——向基类传递参数
运用基类的初始化,在声明派生类时,直接赋予参数。
包含初始化列表的派生类函数构造函数

#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
class fish
{
protected :
	bool Freshwaterproperty;
public:
	fish(bool intFreshwaterproperty):Freshwaterproperty(intFreshwaterproperty)
	{};
	void swim()
	{
		if (Freshwaterproperty == true)
			cout << "the fish  is in lake " << endl;
		else
			cout << "the fish is in sea" << endl;
	}
};
class seafish:public fish
{
public:
	seafish():fish(true)
	{
	}
};
class lakefish :public fish
{
public:
	lakefish():fish(false)
	{
	}
};
int main()
{
	seafish lunch;
	lunch.swim();
	lakefish dinner;
	dinner.swim();
    return 0;
}

3 派生类覆盖基类函数及处理方法

#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
class fish
{
protected :
	bool Freshwaterproperty;
public:
	fish(bool intFreshwaterproperty) :Freshwaterproperty(intFreshwaterproperty)
	{};
	void swim()
	{
		if (Freshwaterproperty == true)
			cout << "the fish  is in lake " << endl;
		else
			cout << "the fish is in sea" << endl;
	}
};
class seafish:public fish
{
public:
	seafish():fish(true)
	{
	}
	void swim()
	{
		cout << "the seafish is fast " << endl;
	}
};
class lakefish :public fish
{
public:
	lakefish():fish(false)
	{
	}
	void swim()
	{
		cout << "the lakefish is slow " << endl;
	}
};
int main()
{
	seafish lunch;
	lunch.swim();

	lakefish dinner;
	dinner.swim();
	return 0;
}

输出结果为派生类的方法,将基类方法覆盖:
在这里插入图片描述
解决方法:
1在派生类方法里面调用积累函数

//上面的例子的变化之处
class lakefish :public fish
{
public:
	lakefish():fish(false)
	{
	}
	void swim()
	{
	    fish::swim();
		cout << "the lakefish is slow " << endl;
	}
};

在这里插入图片描述
2在主调函数中运用实例化对象访问时后面运用作用域符访问

int main()
{
	seafish lunch;
	lunch.swim();

	lakefish dinner;
	dinner.fish::swim();
	return 0;
}

在这里插入图片描述

私有继承

私有继承与公有继承的不同之处:
1 在声明派生类时运用class seafish:private fish
2 运用私有继承后,其他seafish的派生类不能访问基类的成员,要想访问基类的成员,需要另外声明一个公有继承的类。更不能在类外部运用实例化对象对基类的成员(属性及方法)进行访问。
3 基类的成员只能在派生类声明里访问

4 一般情况下,尽量不使用私有继承,必要时,更好选择是将基类对象作为派生类的私有成员

#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
class fish
{
protected :
	bool Freshwaterproperty;
public:
	fish(bool intFreshwaterproperty) :Freshwaterproperty(intFreshwaterproperty)
	{};
	void swim()
	{
		if (Freshwaterproperty == true)
			cout << "the fish  is in lake " << endl;
		else
			cout << "the fish is in sea" << endl;
	}
};
class seafish:private fish
{
public:
	seafish():fish(true)
	{
	}
	void swim2()
	{
		cout << "the seafish is fast " << endl;
		fish::swim();
	}
};
class lakefish :public fish
{
public:
	lakefish():fish(false)
	{
	}
	void swim()
	{
		cout << "the lakefish is slow " << endl;
	}
};
int main()
{
	seafish lunch;
	lunch.swim2();
	
	lakefish dinner;
	dinner.swim();
	dinner.fish::swim();
	return 0;
}

在这里插入图片描述

保护继承

保护继承与私有继承的不用之处在于:保护继承派生类的派生类可以访问基类。

多继承

class bird :public A,public B ,…

多态

1 使用虚函数实现多态行为
多态:运用函数参数调用类的方法时,将派生类对象视为基类对象,并执行派生的函数,无需关心引用指向的是那样一个类。
实现多态重要的一点是:在访问的基类函数前面添加virtual

#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
class fish
{
protected :
	bool Freshwaterproperty;
public:
	fish(bool intFreshwaterproperty) :Freshwaterproperty(intFreshwaterproperty)
	{};
	 virtual void swim()
	{
		if (Freshwaterproperty == true)
			cout << "the fish  is in lake " << endl;
		else
			cout << "the fish is in sea" << endl;
	}
};
class seafish:public fish
{
public:
	seafish():fish(true)
	{
	}
	void swim()
	{
		cout << "the seafish is fast " << endl;
	}
};
class lakefish :public fish
{
public:
	lakefish():fish(false)
	{
	}
	void swim()
	{
		cout << "the lakefish is slow " << endl;
	}
};
void fishfuntion(fish& inputfishclass)
{
	inputfishclass.swim();
};
int main()
{
	seafish lunch;
	fishfuntion(lunch);
	lakefish dinner;
	fishfuntion(dinner);
	return 0;
}

输出结果如下:
在这里插入图片描述

2 纯虚函数——抽象基类
1 即与1的类似,在virtual void swim=0;即指定了派生类的方法及特征

2 抽象基类要求派生类必须对其方法swim进行定义,

#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
class fish
{
protected :
	bool Freshwaterproperty;
public:
	fish(bool intFreshwaterproperty) :Freshwaterproperty(intFreshwaterproperty)
	{}
	virtual void swim() = 0;
	
};
class seafish:public fish
{
public:
	seafish():fish(true)
	{
	}
	void swim()
	{
		cout << "the fish  is in sea " << endl;
		cout << "the seafish is fast " << endl;
	}
};
class lakefish :public fish
{
public:
	lakefish():fish(false)
	{
	}
	void swim()
	{
		cout << "the fish  is in lake " << endl;
		cout << "the lake fish is slow " << endl;
	}
};
void fishfuntion(fish& inputfishclass)
{
	inputfishclass.swim();
};
int main()
{
	seafish lunch;
	fishfuntion(lunch);
	lakefish dinner;
	fishfuntion(dinner);
	return 0;
}

3使用虚函数释放内存
当类里面含有析构函数时,将析构函数表示为虚函数 virtual ~Base();确保当以基类作为函数的指针时,释放派生类的内存。防止资源为释放,内存泄漏问题。
4 运用虚继承解决菱形问题
在实现多继承时,为多继承的基类又来同一个基类,此时在用实例化对象访问基类的成员时,将产生二义性,即菱形问题。
解决的方法时在多继承的每一个类,在继承同一个基类时, public virtul 基类名

猜你喜欢

转载自blog.csdn.net/qq_33713592/article/details/84074322
今日推荐