C++面向对象-22-多态基本语法

前面内容学习了继承,在面向对象三大核心概念,我们学习完了封装,继承,剩下一个多态。这篇开始学习多态的基本概念和C++中多态基本使用。

1. 多态分两类

静态多态:函数重载和运行符重载属于静态多态,服用函数名
动态多态:派生类和虚函数实现运行时多态

这块的知识点和Java中思想是一样的。例如Java中经常遇到的面试题,你能说一下Java中的多态吗。一般来说标准答案是这样的:

      多态是面向对象三大核心,多态就是有多种形态,分两种情况。1)在单个类中,多态的表现为函数的重载,就是共用一个函数名,参数个数,参数类型不同,这些同名函数完成不同的功能,这就是单个类中的多态表现。 2)在继承中,子类继承父类,子类可以修改父类中已有的函数的行为,这个动作叫做重写。就是子类重写父类的方法,这也是多态。然后适当举例,工作中用到多态的例子,这样回答,面试官基本都满意,很清楚表达你对面向对象三大特点的掌握。

      在C++中,多态也是这两点。也分成静态多态和动态多态。结合上面Java中知识,理解上面静态多态和动态多态两类不难。第一类也是函数重载,C++中多了一个运算符重载。派生类也就是子类继承中重写父类方法,又多了一个虚函数而已。

 

2. 静态多态和动态多态区别:
静态多态的函数地址早绑定-编译阶段确定函数地址
动态多态的函数地址晚绑定-运行阶段确定函数的地址

这两点区别,没什么解释的,一个发生在编译阶段,一个发生在运行阶段。

 

3.静态绑定的代码示例

先看看这段代码,理解下什么是静态绑定

#include <iostream>
using namespace std;

//动物基类
class Animal{
public:
    void speak()
    {
        cout << "动物在叫" << endl;
    }
};

//猫类
class Cat : public Animal
{
public:
    void speak()
    {
        cout << "猫在叫" << endl;
    }
};

void doSpeak(Animal &animal)
{
    animal.speak();
}

void test01()
{
    Cat cat;
    doSpeak(cat);
}

int main()
{
    test01();
    system("pause");
}

在看运行结果之前,肯定会好奇,打印的是 “动物在叫” 还是猫在叫。在方法doSpeak中,参数是一个Animal的对象的引用。但是我们在test01中调用doSpeak()函数传入的是一个cat对象。

看到上面输出,输出的Animal基类中的speak(), 现象是传入的是一个派生类(Cat类)对象,执行的方法却是基类的方法,这个就是动态绑定,在编译阶段,编译器就把这个标记为执行基类中的speak()方法,所以输出调用的是基类中的speak方法。

本意上我们创建一个猫对象,应该是想打印“猫在叫”。也就是我们不希望进行静态绑定,而是进行动态绑定,也就是在运行的时候,动态绑定函数地址,调用派生类中方法,下面使用virtual来实现动态绑定。

 

4.虚函数实现动态绑定

这里虚函数就是在基类中成员函数前面加上关键字virtual,这个函数就叫虚函数。

#include <iostream>
using namespace std;

//动物基类
class Animal{
public:
    //虚函数实现动态绑定
    virtual void speak()
    {
        cout << "动物在叫" << endl;
    }
};

//猫类
class Cat : public Animal
{
public:
    void speak()
    {
        cout << "猫在叫" << endl;
    }
};

void doSpeak(Animal &animal)
{
    animal.speak();
}

void test01()
{
    Cat cat;
    doSpeak(cat);
}

int main()
{
    test01();
    system("pause");
}

就添加了一个virtual关键字,让speak函数变成虚函数,输出的结果却是 “猫在叫”。

在test01函数中doSpeak(xx),在编译的时候不能进行静态绑定,确定函数地址。而是需要在运行的时候,根据传入的参数,例如这里是猫,或者传入的是狗,它就会动态去找猫里面的speak函数或狗中的speak函数,这个就叫动态搬绑定,动态确定函数speak()的地址。

总结:
动态多态满足条件
1)有继承关系
2)子类重写父类的虚函数

动态多态的使用:

父类的指针或引用,指向子类对象。在上面代码doSpeak(Animal &animal) 相当于 Animal & animal = cat; 当前还没有用指针写一个例子,后面学习。

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值