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

发布时间 2023-12-28 13:43:12作者: 山雨欲來風滿楼

先说结论:

多态是一种思路概念。

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

大致分为两种。

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