浅谈C++中继承与多态的区别
众所周知,C++有三大特性和五大原则,这三大特性分别是:封装、继承和多态。然而继承和多态这两个特性是许多人容易混淆的。
今天我们就来聊聊C++中继承和多态的区别。
看文章之前,别忘了关注我们,在我们这里,有你所需要的干货哦!
1.基础概念
(1)继承
指可以让某个类型的对象,获得另一种类型对象属性的方法。实际上就是类与类之间可以共用代码,实现代码重用。
继承支持按级分类的概念。它可以使用现有类的所有功能,并在无需重新编写原来类的情况下对这些功能进行扩展。
继承的过程:从一般到特殊的过程。
实现继承的方式:可以通过 “继承”(Inheritance)和“组合”(Composition)来实现。
与继承相关的类类型:
**基类:**被继承的类,即"父类"或“超类”。
**派生类:**基于基类创建的新类,又称“子类”。派生类可以访问基类中所有的非私有成员。
//派生类创建格式:
class derived-class : access-specifier base-class
/*
①access-specifier表示继承类型。我们几乎不使用 protected 或 private 继承,通常使用 public 继承。若如果未使用访问修饰符 access-specifier,则默认为private。
②base-class表示已有基类
*/
代码实现:
// 基类
class Animal {
// eat() 函数
// sleep() 函数
};
//派生类
class Dog : public Animal {
// bark() 函数
};***继承几种类型:***继承类型是通过上面讲解的访问修饰符 access-specifier 来指定的。
private:私有继承
基类private成员 不能继承 基类public、protected成员,可以继承,在派生类中需要通过private访问
protected:保护继承:
基类private成员 不能继承 基类public成员,可以继承,在派生类中相当于是protected访问 基类protected成员,可以继承,在派生类中相当于是protected访问
public:公有继承:
基类private成员 不能继承 基类public成员,可以继承,在派生类中相当于是public访问 基类protected成员,可以继承,在派生类中相当于是protected访问
private派生
变为private成员
变为private成员
不可见
基类的非私有成员都成为派生类的私有成员
protected派生
变为protected成员
变为private成员
不可见
基类的非私有成员在派生类中的访问属性都降一级
public派生
仍为public成员
仍为protected成员
不可见
基类的非私有成员在派生类中的访问属性保持不变
(2)多态
按字面的意思就是多种形态,指一个类实例的相同方法在不同情况下有不同表现形式。
多态机制使内部结构不同的对象可以共享相同的外部接口。即子类可以重写父类的某个函数,从而为这个函数提供不同于父类的行为。一个父类的多个子类可以为同一个函数提供不同的实现,从而在父类这个公共的接口下,表现出多种行为。
多态的使用场景:当类之间存在层次结构,并且类之间是通过继承关联时。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
在C++中,多态性的实现和联编(也称绑定)这一概念有关。主要分为静态联编和动态联编两种
静态联编支持的多态性 称为编译时多态性(静态多态性)。在C++中,编译时多态性是通过函数重载和模板实现的。利用函数重载机制,在调用同名函数时,编译系统会根据实参的具体情况确定索要调用的是哪个函数。
动态联编所支持的多态性 称为运行时多态(动态多态)。在C++中,运行时多态性是通过虚函数来实现的。
再举一个通俗易懂的例子:比如购买车票,普通人是全价票;学生是半价票等。
多态实现的三个条件:
①必须是公有继承 ②必须是通过基类的指针或引用 指向派生类对象 访问派生类方法 ③基类的方法必须是虚函数,且完成了虚函数的重写
例如:
//tips:虚函数指在类的成员函数前加**virtual**关键字。
#include <iostream>
using namespace std;
// 基类
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
// 派生类
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
// 程序的主函数
int main( )
{
Shape *shape;
Rectangle rec(10,7);
// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();
return 0;
}
运行结果:Rectangle class area
(Tips: shape中的area函数若没有用virtual定义,则无法实现调用派生类中area函数的目的)
2.继承和多态的区别
区别:
1.多态的实现要求必须是共有继承。
2.继承关系中,并不要求基类方法一定是虚函数。而多态时,要求基类方法必须是虚函数。
3.多态:子类重写父类的方法,使得子类具有不同的实现。且运行时,根据实际创建的对象动态决定使用哪个方法。
总结
在面向对象过程中,通常我们会以多个对象共有的特性作为基类进行创建。然后利用继承的特性,对基类进行派生。
基类与派生类存在相同的方法,但是有不同的方法体。当调用这些方法体时就需要利用C++的多态性质,根据对象的特性有选择的对方法进行调用。即多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。
其它干货
引用
https://blog.csdn.net/qq_37185716/article/details/75044620
https://www.runoob.com/cplusplus/cpp-inheritance.html
https://www.runoob.com/cplusplus/cpp-polymorphism.html
Last updated