先说结论:
多态是一种思路概念。
不同的语言实现方式不太一样。
大致分为两种。
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