目录 Table of Contents
面向对象程序设计之多态
前面课程一直在说, 所有的面向对象的语言, 要解决的一个事情就是不要造相同的轮子.
说得通俗点就是一个代码不要写两遍, 也可以理解成代码的复用
代码复用的两种体现形式 :
-
继承
-
共用相同的函数
父类的指针或者引用指向子类的对象, 编译器是允许的
但是编译器不让你用子类的指针访问父类的对象
多态
什么是多态 ?
多态就是可以让父类指针有多种形态, 同一个函数代码, 当我传一个父类对象的时候, 它调用的是父类的函数, 当我传一个子类对象的时候, 它调用的是子类的函数
C++ 中是通过虚函数实现多态, 就是在函数前面加上 virtual
关键词
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
class Shape
{
public:
virtual double area()
{
return 0;
}
};
class Circular:public Shape
{
private:
double r;
public:
Circular(double r)
{
this->r = r;
}
double area() // 如果这两个函数名字不一样了, 那就意味着我下面这个函数是没法共用的
{
return PI*r*r;
}
};
void PrintArea(Shape* s) // 这个函数的参数是父类的一个指针类型
{
/*
当我们想使用这个函数的时候, 你可以创建一个子类的对象, 然后把子类的对象传进来
*/
s->area();
}
我可能不止有圆形一个子类, 我可能还有三角形正方形等等多个子类, 但是只要我重写了父类里面的 area()
函数, 那就意味着函数 PrintArea()
, 所有的子类都可以共用.
这个时候里面有一个恶心的地方, 就是父类里面的这个函数, 除了提供 area()
这么一个函数之外, 它没有别的功能
因为它就是个 shape 形状, 它没法定义长宽高半径这种成员变量, 我只能定义一个获取面积的这样一个函数, 因为任何一个子类都会有一个计算自己面积的功能. 并且父类这个面积函数里面也没法写别的内容, 因为具体的面积怎么去计算, 是由子类来决定的.
所以这个父类它唯一的意义是, 规定了你们必须要实现这个接口, 实现了接口以后才可以使用 PrintArea()
函数
那如果这样的话, 我们可以写得更加简单了 :
class Shape
{
public:
virtual double area() = 0;
};
这就是纯虚函数
纯虚函数
-
虚函数的目的是提供一个统一的接口函数, 被继承的子类所重载 (重写), 以多态的形式被调用
-
如果父类中的函数没有任何实现的意义, 那么可以定义成纯虚函数 :
virtual 返回类型 函数名(参数列表) = 0;
-
含有纯虚函数的类被称为抽象类 (abstract class), 不能创建对象
-
虚函数可以被直接使用, 也可以被子类重写后以多态的形式调用, 而纯虚函数必须在子类中实现该函数才可以使用
如果父类里面有纯虚函数的话, 那么子类是必须要重写这个函数的, 否则编译器报错