C++——Polymorphism 多态

多态,字面理解就是一个事物的多种形态。实际上是:不同的事物对同一行为做出的不同的反应。

C++中的多态:由继承而产生的相关的不同的类, 其对象对同一消息会作出不同的响应。

多态性是面向对象程序设计的一个重要特征, 能增加程序的灵活性。 可以减轻系统升级,维护,调试的工作量和复杂度。

 

1、赋值兼容 Assign Compatible

在需要基类对象的任何地方, 都可以使用公有派生类的对象来替代。只有在公有派生类中才有赋值兼容, 赋值兼容是一种默认行为, 不需要任何的显示的转化步骤。

三种:only three!

1、派生类的对象可以赋值给基类对象。
2 、派生类的对象可以初始化基类的引用。
3 、派生类对象的地址可以赋给指向基类的指针。

 

2、多态

静多态:

静多态:通过命名倾轧在编译阶段实现

(1)func(int a, int b) -->func_i_i

(2)func(float ,double d) -->func_f_d

(动)多态

多态实现条件:

(1)父类中有虚函数

(2)子类中覆写(override)了父类的虚函数

(3)将子类对象地址赋给父类的指针 并发生虚函数调用。

注意:

1、声明虚函数的方法:在前边加 virtual 构成虚函数。声明时加,后边用到不用加。

2、 覆写的函数,不一定同父类的访问方式(公有、私有、保护)一致。。看子类需求自定!

3、三者区别:

覆写(override)

发生在父子类中。父类中函数有虚函数声明,子类中,同参、同名、同返回 的函数之间构成覆写

重载        (overload)

同一作用域,函数名相同,参数列表不同

shadow

发生在父子类之间的同名成员(只看名字,不看参数)

2.1虚函数与多态

(1)virtual是声明虚函数的关键字,virtual void function();

(2)虚函数在派生类中仍为虚函数。

(3)覆写条件:发生在父子类的继承关系中,且函数 同参、同名、同返回值。

(4)子类中的覆写函数,可以是任意类型的访问方式(公有、私有、保护),看子类自己需求规定。

2.2纯虚函数与多态

纯虚函数, 是一类没有实现体, 且被"初始化"为零的函数。 格式: virtual void draw() = 0;

注意:

(1)纯虚函数只有声明,没有实现。 virtual void draw() = 0;被初始化为0。

(2)含有纯虚函数的类,称为“Abstract Base Class”(抽象基类)。抽象基类不可实例化,也就是不能定义类对象。其存在的意义就是被继承,提供族类的公共接口。

(3)如果一个基类中声明了纯虚函数,此基类就是抽象基类。派生类中如果没有该函数的定义,那么在该派生类中仍为纯虚函数,则该派生类也是纯虚基类。(也就是说:A含有纯虚函数是抽象基类,B继承A,如果B中没有纯虚函数的定义,那么B也不能定义对象。)

2.3虚析构

含有虚函数的类, 析构函数也应该声明为虚函数, 称为虚析构函数。

在 delete 父类指针, 指向的堆上子类对象时, 会调用子类的析构函数, 实现完整析构。

堆中 含有虚函数的时候,将其析构函数一并置为 virtual ~Dog();栈中自处理,没这么多事。

记住含虚函数的析构的时候 加个 virtual ~ 就完事了。

    Animal();
    virtual ~Animal();

 

 

 

### C++ 中封装、继承和多态的概念及用法 #### 封装 (Encapsulation) 封装是一种将数据(属性)和操作这些数据的方法绑定在一起的技术,同时隐藏对象内部的具体实现细节。通过访问控制机制(`public`, `protected`, 和 `private`),可以保护类的数据不被外部随意修改。 以下是封装的一个简单示例: ```cpp class EncapsulationExample { private: int data; // 私有成员变量,无法直接访问 public: void setData(int value) { // 提供公共接口设置私有数据 data = value; } int getData() const { // 提供公共接口获取私有数据 return data; } }; ``` 上述代码展示了如何利用封装技术保护数据的安全性[^1]。 --- #### 继承 (Inheritance) 继承是面向对象编程中的一个重要特性,它允许创建一个新类(派生类或子类)基于已有的类(基类或父类)。这样可以减少冗余代码并提高可维护性。 C++ 支持单继承以及多重继承。然而,在多重继承中可能会遇到“菱形继承”问题,这可以通过定义虚基类来解决[^2]。 下面是一个简单的继承例子: ```cpp // 基类 class Animal { public: void eat() { std::cout << "Eating..." << std::endl; } }; // 派生类 class Dog : public Animal { public: void bark() { std::cout << "Barking..." << std::endl; } }; ``` 在这个例子中,`Dog` 类继承自 `Animal` 类,并扩展了自己的行为——`bark()` 方法。 对于多重继承的情况,考虑如下场景: ```cpp class A {}; class B : virtual public A {}; // 虚拟继承 class C : virtual public A {}; class D : public B, public C {}; int main() { D objD; return 0; } ``` 这里使用了虚拟继承以避免因多次继承而导致的对象重复实例化问题。 --- #### 多态 (Polymorphism) 多态是指同一个接口可以根据调用它的具体对象而表现出不同的形式。在 C++ 中主要分为静态多态性和动态多态性两大类。前者通常由函数重载或者运算符重载实现;后者则依赖于虚函数完成运行时的选择逻辑[^3]。 ##### 动态多态性的典型应用 —— 使用虚函数 当希望某个特定功能能够在不同类型的对象间共享相同的名字却有不同的实际执行效果时,则需要用到虚函数。例如: ```cpp #include <iostream> using namespace std; class Shape { public: virtual void draw() = 0; // 纯虚函数声明 }; class Circle : public Shape { public: void draw() override { cout << "Drawing a circle." << endl; } }; class Rectangle : public Shape { public: void draw() override { cout << "Drawing a rectangle." << endl; } }; void displayShape(Shape* shapePtr) { shapePtr->draw(); } int main() { Shape *shapeObj1 = new Circle(); Shape *shapeObj2 = new Rectangle(); displayShape(shapeObj1); // 输出:Drawing a circle. displayShape(shapeObj2); // 输出:Drawing a rectangle. delete shapeObj1; delete shapeObj2; return 0; } ``` 此程序片段说明了即使两个指针指向的是不同类型的实际实体,但由于它们都实现了共同的抽象基础类型所规定的协议,因此能够统一处理[^4]。 --- #### 综合案例分析 综合以上三个概念的应用,我们可以构建更复杂的软件结构模型。比如设计一款游戏引擎框架,其中涉及各种角色及其技能树管理等复杂交互关系,都可以借助 OOP 的三大支柱去简化开发流程并增强系统的灵活性与扩展能力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值