C++ 多態(2): 純虛函數, 抽象類和接口類

在這裏插入圖片描述

注:轉載請標明原文出處鏈接:https://xiongyiming.blog.csdn.net/article/details/100711676


1 純虛函數和抽象類

如下圖所示,純虛函數沒有函數體,在函數聲明後加上=0 .

在這裏插入圖片描述


在這裏插入圖片描述

這裏,我們把含有純虛函數的類稱之爲 抽象類


在這裏插入圖片描述


抽象類的特性:
(1) 抽象類無法實例化對象;
(2) 抽象類的子類也爲是抽象類;

例如,如下圖所示,在定義父類Person時,我們不知道虛函數work() 和printInfo()函數不知道要實現什麼功能時,可以直接使用純虛函數。

在這裏插入圖片描述

接下來,對於子類Worker繼承父類Person時,純虛函數也繼承下來,對於printInfo()函數想實現什麼功能,就可以寫函數體了,此時,printInfo()函數變成了虛函數。work() 還不知道要實現什麼功能時,可以繼續使用純虛函數。

在這裏插入圖片描述

然後,對於子類Dustman繼承父類Person時,純虛函數也繼承下來,對於work() 和printInfo()函數想實現什麼功能,就可以寫函數體了,此時,work() 和printInfo()函數變成了虛函數。

在這裏插入圖片描述



代碼示例


要求

純虛函數抽象類

  1. Person類
    成員函數:構造函數 虛析構函數 純虛函數work
    數據成員:名字m_strName

  2. Worker類
    成員函數:構造函數 虛析構函數 work
    數據成員:年齡m_iAge

  3. Dustman類
    成員函數:構造函數 work


Person.h

#pragma once
#include<iostream>
#include<string>

using namespace std;

class Person
{
public:
	Person(string name);
	virtual void work() = 0;//純虛函數
	virtual ~Person(); //虛析構函數

private:
	string m_strName;
};

Person.cpp

#include"Person.h"
using namespace std;


Person::Person(string name)
{
	m_strName = name;
}


Person::~Person()
{
	cout << "~Person()" << endl;
}


<br>

Worker.h

#pragma once
#include<iostream>
#include<string>
#include"Person.h"
using namespace std;

class Worker :public Person
{
public:
	Worker(string name, int age);
	virtual ~Worker();
	virtual void work();

private:
	int m_iAge;
};

Worker.cpp

#include<iostream>
#include<string>
#include"Worker.h"
using namespace std;

Worker::Worker(string name, int age):Person(name)
{
	m_iAge = age;
}



Worker::~Worker()
{
	cout << "~ Worker()" << endl;
}

void Worker::work()
{
	cout << "work()" << endl;
}

Dustman.h

#pragma once
#include<iostream>
#include<string>
#include"Worker.h"
using namespace std;

class Dustman :public Worker 
{
public:
	Dustman(string name, int age);
	virtual void work();


};

Dustman.cpp

#include<iostream>
#include<string>
#include"Dustman.h"

using namespace std;

Dustman::Dustman(string name, int age):Worker(name, age)
{

}

void Dustman::work()
{
	cout << "Dustman 掃地 " << endl;
}

main.cpp

#include<iostream>
#include"Person.h"
#include"Worker.h"
#include"Dustman.h"
using namespace std;



/***************
純虛函數抽象類
1.Person類
	成員函數:構造函數 虛析構函數 純虛函數work
	數據成員:名字m_strName

2. Worker類
	成員函數:構造函數 虛析構函數 work
	數據成員:年齡m_iAge

3. Dustman類
	成員函數:構造函數 work
	
***************/

int main(void)
{
	/* 父類Person work()爲純虛函數
	子類Worker work()爲虛函數 */
	Worker worker("zhangsan", 20);
	worker.work();
	cout << "--------------" << endl;


	/* 父類Person work()爲純虛函數
	子類Worker work()爲虛函數
	子類Dustman work()爲虛函數*/
	Dustman dustman("lisi", 50);
	dustman.work();

	cin.get();
	return 0;

}

運行結果

在這裏插入圖片描述



2 接口類

接口類:僅含有純虛函數的類稱之爲接口類。

在這裏插入圖片描述
接口類更多的表達一種能力或協議。

如下所示,Flyable接口類含有兩個純虛函數,那麼只有繼承這個類,去實現起飛和降落兩個函數後,Flyable類才具有能力/協議。

在這裏插入圖片描述


在這裏插入圖片描述

再舉一個例子

在這裏插入圖片描述

在這裏插入圖片描述



代碼示例


要求

接口類

  1. Flyable類
    成員函數:takeoff land

  2. Plane類
    成員函數:構造函數 虛析構函數 takeoff land printCode
    數據成員:m_strCode

  3. FightPlane類
    成員函數:構造函數 takeoff land

4 全局函數flyMatch(Flyable *f1,Flyable *f2)


Flyable.h

#pragma once

class Flyable
{
public:
	virtual void takeoff() = 0;//純虛函數
	virtual void land() = 0;//純虛函數

};

Plane.h

#pragma once
#include<iostream>
#include<string>
#include"Flyable.h"

using namespace std;

class Plane :public Flyable
{
public:
	Plane(string code);
	virtual void takeoff();
	virtual void land();
	void printCode();

private:
	string m_strCode;
};

Plane.cpp

#include<iostream>
#include<string>
#include"Plane.h"

using namespace std;

Plane::Plane(string code)
{
	m_strCode = code;
}

void Plane::takeoff()
{
	cout << "Plane--takeoff() " << endl;
}


void Plane::land()
{
	cout << "Plane--land() " << endl;
}


void Plane::printCode()
{
	cout << "m_strCode= " << m_strCode << endl;
}

FightPlane.h

#pragma once
#include<iostream>
#include<string>
#include"Plane.h"

using namespace std;

class FightPlane:public Plane
{
public:
	FightPlane(string code);
	virtual void takeoff();
	virtual void land();
};

FightPlane.cpp

#include<iostream>
#include<string>
#include"FightPlane.h"

using namespace std;

FightPlane::FightPlane(string code) :Plane(code)
{

}

void FightPlane::takeoff()
{
	cout << "FightPlane--takeoff() " << endl;
}

void FightPlane::land()
{
	cout << "FightPlane--land() " << endl;
}

main.cpp

#include<iostream>
#include"FightPlane.h"

using namespace std;

/***************
接口類
1.Flyable類
	成員函數:takeoff  land
	
2. Plane類
	成員函數:構造函數 虛析構函數 takeoff  land printCode
	數據成員:m_strCode

3. FightPlane類
	成員函數:構造函數  takeoff  land
	
4 全局函數flyMatch(Flyable *f1,Flyable *f2)

***************/

void flyMatch(Flyable *f1, Flyable *f2)
{
	f1->takeoff();
	f1->land();

	cout << "-------------------" << endl;

	f2->takeoff();
	f2->land();

}

int main(void)
{
	Plane p1("001");
	Plane p2("002");
	p1.printCode();
	p2.printCode();
	flyMatch(&p1, &p2);

	cout << "-  -  -  -  -  -  -  -  - " << endl;

	FightPlane p3("003");
	FightPlane p4("004");
	p3.printCode();
	p4.printCode();
	flyMatch(&p3, &p4);

	cin.get();
	return 0;
}

運行結果

在這裏插入圖片描述




參考資料

[1] C++遠征之多態篇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章