【Java和C++】什么是多态

2023-09-20 17:28:32

2023年9月20日,周三上午

今天写作业的时候遇到了多态,但我感觉自己多多态还是不够理解,于是又深入研究了一下。

不过,我觉得我写的这篇文章还不够完整,比如说没提到什么时候适合使用多态,以后有空再写上吧。


目录


什么是多态

多态允许不同类的对象对相同的消息(方法)作出不同的响应。

通俗来说就是,对于同一个函数makeSound,Animal类的对象的响应是输出"发出声音",Cat类的对象的响应是输出“喵喵...”,Dog类的对象的响应是输出“汪汪...”

多态性使得程序能够以一种通用的方式处理不同类型的数据或对象,而无需关心它们的具体类型。

在不同的编程语言中,多态性的实现方式和语法细节可能有所不同,但多态性的核心思想是相同的:允许不同类型的对象在统一的接口下表现出不同的行为


Java

在Java中,可以使用以下几种方法来实现多态性:

方法重写(Method Overriding)

这是最常见的多态性实现方式。它允许子类重写父类的方法,从而在调用相同方法名的情况下,根据对象的实际类型来执行不同的方法体。要使用方法重写,子类需要覆盖父类中的方法,并使用@Override注解确保正确地重写了方法。

class Animal {
    void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("汪汪");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("喵喵");
    }
}

接口(Interface)

Java的接口允许不同的类实现相同的接口,然后通过接口引用对象,从而实现多态性。不同的类可以以不同的方式实现接口中的方法。

interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

抽象类(Abstract Class)

抽象类也可以用于实现多态性,类似于接口,子类必须实现抽象类中的抽象方法。

abstract class Animal {
    abstract void makeSound();
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("汪汪");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("喵喵");
    }
}

泛型(Generics)

泛型允许编写通用的代码,以处理不同类型的数据。通过使用泛型类型参数,可以在编译时确定对象的类型,并执行相应的操作。


C++

在C++中,有两种主要方式可以实现多态性:虚函数和函数指针。

但是,虚函数是实现多态性的主要和推荐方式

虚函数(Virtual Functions)

在C++中,可以将成员函数声明为虚函数,以实现多态性。这通常用于面向对象编程中的继承和多态。虚函数通过在基类中声明并在派生类中重写来实现。这样,派生类可以为虚函数提供自己的实现,而基类的指针或引用可以用于调用这些虚函数,具体的调用会根据实际对象的类型而决定。

class Animal {
public:
    virtual void makeSound() {
        std::cout << "动物发出声音" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "汪汪" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "喵喵" << std::endl;
    }
};

使用虚函数时,可以使用基类指针或引用来实现多态性,具体执行哪个版本的函数取决于运行时对象的类型。

函数指针(Function Pointers)

在C++中,也可以使用函数指针来实现多态性。函数指针是指向函数的指针,可以动态指定要调用的函数。可以使用函数指针数组或函数指针成员来实现多态性,根据需要调用不同的函数。

class Animal {
public:
    void (*makeSound)() = nullptr;

    void playSound() {
        if (makeSound != nullptr) {
            makeSound();
        }
    }
};

void animalSound() {
    std::cout << "动物发出声音" << std::endl;
}

void dogSound() {
    std::cout << "汪汪" << std::endl;
}

int main() {
    Animal animal;
    animal.makeSound = animalSound;

    Animal dog;
    dog.makeSound = dogSound;

    animal.playSound(); // 调用 Animal 的声音函数
    dog.playSound();    // 调用 Dog 的声音函数

    return 0;
}

这种方法允许在运行时选择要调用的函数,但相对于虚函数,它更为复杂,需要手动管理函数指针。

总结来说,在C++中,虚函数是实现多态性的主要和推荐方式,因为它更容易使用并且具有更好的可读性和维护性。函数指针可以用于实现多态性,但它通常更适用于特定的高级用例,比如函数回调。虚函数是C++中实现多态性的首选方式

更多推荐

你能想象在亚运赛场打《王者荣耀》吗?

作者:April叶快评:20年前,没人敢相信电竞加入亚运会,但在今年的杭州亚运会,电竞不仅正式成为官方竞赛项目,首次登场还一举成了亚运会“顶流”。你以为打游戏只会毁了你但其实打游戏也能为国争光要说今年杭州亚运会最大的“顶流”是谁那必须是这个项目不仅呼声最高门票价格也最高还是唯一要抽签才能买票的项目门票比演唱会的还难抢哪

自己实现一个简单的vhost-net

框架vhost在网络中的位置如图:要学习具体的框架可以看我之前的文章vhost-net--------深入了解Virtio-networking和vhost-net接下来,我们自己实现一个vhost.vhost-net代码在代码中写了详细注释,就直接上代码了#include<stdio.h>#include<strin

新消费降温,良品铺子还能走多远?

如果时间倒退到多年前,杨红春应该不会料到现在良品铺子的境遇。从2006年创立至今,前半段良品铺子经历了品牌升级,从线下发展到平台电商、社交电商,做APP客户端进行全渠道的营销,把一家曾入不敷出的小店,养成年利润过亿的高端零食大公司,似乎每一步都精准地踏在时代的节骨眼上。行业层面,国内零食市场规模也从杨红春刚创业时的数千

Next.js 13 服务器组件和应用目录完整指南

通过关于使用服务器组件和应用程序目录的最完整和最权威的教程,释放Next.js13的全部潜力。目录Next.js13带来了什么?服务器组件(RSC)布局ServerActions服务器操作EnhancedRouter增强型路由器什么是服务器组件?服务器组件与客户端组件定义服务器组件定义客户端组件App应用目录文件结构托

Docker 架构解析:理解 Docker 引擎和容器运行时

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

【计算机组成原理】读书笔记第四期:从源文件到可执行文件

目录写在开头从源代码到本地代码源代码本地代码的初级形态(这一节有点不严谨)编译器从目标文件到可执行文件启动和库文件DLL文件及导入库可执行文件的运行机制变量和函数的内存地址程序加载时生成栈和堆结尾写在开头本文继续阅读总结《程序是怎样跑起来的》这本书(作者:矢泽久雄)。前三篇博客介绍了这本书的阅读感受,并分别对第一章CP

如何修复msvcp140.dll文件,msvcp140.dll丢失的解决方法

在使用电脑的过程中,可能会遇到提示“msvcp140.dll丢失”的错误。这通常是由于某些程序或游戏在运行时需要调用msvcp140.dll文件,但由于某种原因(如病毒感染、误删等),该文件被删除或损坏,导致程序无法正常运行。解决方法1.重新安装相关程序当出现msvcp140.dll丢失的错误时,首先尝试重新安装出现问

Haproxy集群与常见的Web集群调度器

文章目录1.Web集群调度器概述1.1Web集群调度器简介1.2调度器类别1.2.1常用软件类1.2.2常用硬件类2.Haproxy软件介绍2.1Haproxy简介2.2支持功能2.3主要特性2.4常用调度算法2.4.1轮询:RR(RoundRobin)2.4.2最小连接数:LC(LeastConnections)2.

MongoDB-1入门介绍

NoSQLNoSQL(NoSQL=NotOnlySQL),意即反SQL运动,指的是非关系型的数据库优点1、对数据库高并发读写。2、对海量数据的高效率存储和访问。3、对数据库的高可扩展性和高可用性。弱点:1、数据库事务一致性需求2、数据库的写实时性和读实时性需求3、对复杂的SQL查询,特别是多表关联查询的需求简介Mong

【小沐学NLP】关联规则分析Apriori算法(Mlxtend库,Python)

文章目录1、简介2、Mlxtend库2.1安装2.2功能2.2.1UserGuide2.2.2UserGuide-data2.2.3UserGuide-frequent_patterns2.3入门示例3、Apriori算法3.1基本概念3.2apriori3.2.1示例1--生成频繁项集3.2.2示例2--选择和筛选结

nginx配置指南

nginx.conf配置找到Nginx的安装目录下的nginx.conf文件,该文件负责Nginx的基础功能配置。配置文件概述Nginx的主配置文件(conf/nginx.conf)按以下结构组织:配置块功能描述全局块与Nginx运行相关的全局设置events块与网络连接有关的设置http块代理、缓存、日志、虚拟主机等

热文推荐