首页 > 其他分享 >多态在不同语言间是如何实现的?

多态在不同语言间是如何实现的?

时间:2023-12-28 13:45:49浏览次数:22  
标签:语言 实现 多态 接口 如何 Animal class

先说结论:

多态是一种思路概念。

不同的语言实现方式不太一样。

大致分为两种。

1.接口实现

  •  接口实现,是用于静态语言中。
  • 特点是只声明。

2.继承实现。

  • 继承实现,是动态语言中。
  • 特点是,父类写个基本的,子类重写父类。
  • 就是覆盖着写,来实现。

举例:

java中的接口示例:

interface Animal {
    void makeSound();//注意这里
}

class Dog implements Animal {
    public void makeSound() {
        System.out.println("Woof!");
    }
}

class Cat implements Animal {
    public void makeSound() {
        System.out.println("Meow!");
    }
}

public class InterfaceExample {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        Animal myCat = new Cat();
        
        myDog.makeSound(); // 输出: Woof!
        myCat.makeSound(); // 输出: Meow!
    }
}

 

 java中的继承举例

class Animal {void makeSound() {
        System.out.println("Some sound!");// 注意这里
    }
}

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

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

public class InheritanceExample {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        Animal myCat = new Cat();
        
        myDog.makeSound(); // 输出: Woof!
        myCat.makeSound(); // 输出: Meow!
    }
}

 

其他语言举例:

go语言中接口实现:

package main

import "fmt"

// 定义一个接口
type Animal interface {
    Speak() string
}

// 定义几个实现了 Animal 接口的类型
type Dog struct{}
func (d Dog) Speak() string {
    return "Woof!"
}

type Cat struct{}
func (c Cat) Speak() string {
    return "Meow!"
}

type Cow struct{}
func (c Cow) Speak() string {
    return "Moo!"
}

func main() {
    // 创建一个 Animal 类型的切片,里面可以放任何实现了 Animal 接口的类型的实例
    animals := []Animal{Dog{}, Cat{}, Cow{}}
    
    // 遍历切片,调用每个元素的 Speak 方法
    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }
}

 

python语言继承实现

class Animal:
    def make_sound(self):
        print("Some sound!")

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

my_dog = Dog()
my_cat = Cat()

my_dog.make_sound()  # 输出: Woof!
my_cat.make_sound()  # 输出: Meow!

python也可以用鸭子类型来实现:

class Animal:# 所以这个基类就可有可无
    def make_sound(self):
        print("Some sound!")

class Dog():    # 不需要继承
    def make_sound(self):
        print("Woof!")

class Cat():    # 不需要继承
    def make_sound(self):
        print("Meow!")

my_dog = Dog()
my_cat = Cat()

my_dog.make_sound()  # 输出: Woof!
my_cat.make_sound()  # 输出: Meow!

C语言举例

我看不懂,就放在这把:

AI说有运行时多态和编译时多态。

用虚函数来实现。我没太理解,就放在这里把。

运行时多态,也称为动态多态,是通过虚函数和继承来实现的。

#include <iostream>

// 基类
class Base {
public:
    virtual void show() { // 虚函数
        std::cout << "Base show" << std::endl;
    }
};

// 派生类
class Derived : public Base {
public:
    void show() override { // 重写虚函数
        std::cout << "Derived show" << std::endl;
    }
};

int main() {
    Base* b;       // 基类指针
    Derived d;     // 派生类对象
    b = &d;        // 指针指向派生类对象

    b->show();     // 调用派生类的 show 方法

    return 0;
}

 

AI的总结:

Q:粗略的来讲,多态有2种实现方式,在静态语言中,倾向于用接口来实现,比如go,java。在动态语言中,倾向于继承来实现,比如python,java。我理解对吗?

AI:您的理解基本正确,但需要澄清一些细节。多态确实有两种常见的实现方式,但接口和继承都可以在静态和动态语言中使用,而不是一种语言类型专属。以下是对多态实现方式的更精确描述:

 接口(Interface-based Polymorphism)

接口定义了一组方法签名,但不实现这些方法。任何实现了接口的类都必须提供这些方法的具体实现。在静态类型语言中,接口是一种常见的实现多态的方式,因为它们提供了一种明确的契约,确保实现类遵循特定的方法签名。

- Go: Go 使用接口来实现多态。在 Go 中,接口是隐式实现的,即如果一个类型提供了接口中所有方法的实现,那么它就实现了该接口,无需显式声明。
- Java: Java 同样支持接口,并且需要显式地声明一个类实现了某个接口。

继承(Inheritance-based Polymorphism)

通过继承,派生类继承了基类的特性和行为。派生类可以扩展或覆盖(重写)基类的方法,从而提供不同的行为。这种覆盖基类方法的能力是实现多态的关键。

- Python: Python 是一种动态类型语言,它通过鸭子类型(duck typing)支持多态。在 Python 中,继承是实现多态的一种方式,但不需要接口来实现多态,因为 Python 不强制类型检查。
- Java: Java 同时支持接口和继承。虽然 Java 是静态类型语言,但它允许通过继承和覆盖基类方法来实现多态。

不同的语言可能对接口和继承的实现和语法有所不同,但它们的核心概念在大多数面向对象的编程语言中是相似的。

静态语言 vs 动态语言

- 静态语言(如 C++, Java, Go)通常在编译时进行类型检查,这意味着对象的类型需要在编译时确定。静态语言倾向于使用接口和抽象类来定义类型的契约,从而实现多态。
- 动态语言(如 Python, Ruby, JavaScript)在运行时进行类型检查,对象的类型可以在运行时改变。动态语言利用鸭子类型来实现多态,即“如果它看起来像鸭子,叫起来也像鸭子,那么它就可以被当作鸭子”。

总结

在静态和动态语言中,接口和继承都可以用来实现多态。关键的区别在于类型系统是如何检查和强制这些契约的。静态类型语言通常需要更显式的契约(如接口和抽象类),而动态类型语言依赖于运行时的行为和鸭子类型。

 

扩展概念:鸭子类型是又是什么?

Python中的鸭子类型,不需要继承,对吗?

  • 对的
  • 实现多态的一种方式,在动态语言python中无需继承
  • 例子:在上面的Python鸭子类型中。

 

参考资料:

chatGPT4.0

 

标签:语言,实现,多态,接口,如何,Animal,class
From: https://www.cnblogs.com/liqi175/p/17932528.html

相关文章

  • keycloak~从login-status-iframe页面总结如何跨域传值~续
    keycloak~从login-status-iframe相关文章,可阅读我的这两篇keycloak~从login-status-iframe页面总结如何跨域传值,keycloak~对接login-status-iframe页面判断用户状态变更。什么是跨域跨域(Cross-Origin)是指在Web开发中,当一个资源(比如JavaScript、CSS、图片等)来自于不同域名、协......
  • 2_C#语言基本类型
    C#语言中常见的类型预定义简单类型名称含义默认值sbyte8位有符号整数0byte8位无符号整数0short16位有符号整数0ushort16位无符号整数0int32位有符号整数0uint32位无符号整数0long64位有符号整数0ulong64为无符号整数0float(I......
  • 如何在敏捷项目中实现高效测试?
    随着软件开发的不断发展,敏捷开发方式脱颖而出,这预示着协作、迭代和高效软件创建的新时代的到来。这一转变的核心是敏捷测试——一种将测试与开发交织在一起的方法,以确保更高的质量、更快的交付和更灵敏的软件产品。本文将深入探讨敏捷测试,包括测试左移、测试自动化以及开发人员与QA......
  • 运营商分配过来的是私网地址,它是如何完成上网的?
    作者:网络之路一天 首发公众号:网络之路博客(ID:NetworkBlog)在实际中,比如图上面最简单的家庭网络,不知道大家发现没有,接光猫下面分配的是192.168.1.0或者192.168.2.0/24的地址,或者拨号分配的是100.100.X.X、10.10.X.X的地址,这些地址可都是私网IP的,在前面提到过,私网IP是无法进入公网的,......
  • 如何使用 Prometheus 监控SpringBoot系统
    公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享在从零开始:使用Prometheus与Grafana搭建监控系统中,主要讲解了如何使用监控系统资源并进行告警,这节主要分享下,如何在业务系统中使用Prometheus来监控业务系统指标,业务系统使用SpringBoot构建。我们要......
  • 如何增加MDK的烧写速度
    jflashlite的烧写速度要比mdk的烧写速度快很多。虽然两者底层都调用了jlink.exe,但是烧写流程有区别。MDK比较保守,不管怎么样先擦除扇区然后再执行写入。jflashlite比较灵活,先进行扇区校验,如果不一致,才执行擦除和写入。这会大大提升微小修改的程序烧写时间。当......
  • 如何在敏捷项目中实现高效测试?
    随着软件开发的不断发展,敏捷开发方式脱颖而出,这预示着协作、迭代和高效软件创建的新时代的到来。这一转变的核心是敏捷测试——一种将测试与开发交织在一起的方法,以确保更高的质量、更快的交付和更灵敏的软件产品。本文将深入探讨敏捷测试,包括测试左移、测试自动化以及开发人员与......
  • 遇到跨端开发或多项目开发时,遇到的一些问题探讨,后端开发语言如何选择?
    ​ 最近有同学问我,做后端开发项目时用php,java,c#,go,pathon...哪个好,从最近阿里云、美团服务器崩溃来看,我想给你最直接的回答是,没有完美的,只有适合自己的。咱们讨论最多的问题就是跨多端开发,以及多项目开发后期所带来的升级、维护等相关问题,接下来就该问题,我发表一点自己的看法,也算是......
  • yum安装的nginx如何安装其他模块
    yum安装nginx没有某一模块,该如何添加第三方模块? 本文将以添加--with-stream模块为例,演示如何去添加新的模块进去。需求:生产有个接口是通过socket通信。nginx1.9开始支持tcp层的转发,通过stream实现的,而socket也是基于tcp通信。实现方法:Centos7.5下yum直接安装的nginx,添加新模......
  • 【Spring教程31】SSM框架整合实战:从零开始学习SSM整合配置,如何编写Mybatis SpringMVC
    目录1流程分析2整合配置2.1步骤1:创建Maven的web项目2.2步骤2:添加依赖2.3步骤3:创建项目包结构2.4步骤4:创建SpringConfig配置类2.5步骤5:创建JdbcConfig配置类2.6步骤6:创建MybatisConfig配置类2.7步骤7:创建jdbc.properties2.8步骤8:创建SpringMVC配置类2.9步骤9:创......