Polymorphism

本文详细介绍了计算机科学中多态性的概念及其在面向对象编程中的应用。探讨了三种多态形式:参数多态、子类型多态及特设多态,并通过实例说明了它们的工作原理。

http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

http://www.cplusplus.com/doc/tutorial/polymorphism/

http://www.codeproject.com/Articles/10900/Polymorphism-in-C


多态

多型英语Polymorphism),是指物件導向程式執行時,相同的訊息可能會送給多個不同的類別之物件,而系統可依據物件所屬類別,引發對應類別的方法,而有不同的行為。簡單來說,所謂多型意指相同的訊息給予不同的物件會引發不同的動作稱之。

比如有動物(Animal)之類別(Class),而且由動物繼承出類別雞(Chicken)和類別狗(Dog),並對同一源自類別動物(父類別)之一訊息有不同的響應,如類別動物有「叫()」之動作,而類別雞會「啼叫()」,類別狗則會「吠叫()」,則稱之為多型。


In computer sciencepolymorphism is a programming language feature that allows values of different data types to be handled using a uniform interface.

1. ad-hoc polymorphism. Ad-hoc polymorphism is supported in many languages using function and method overloading.

2. parametric polymorphismIf all code is written without mention of any specific type and thus can be used transparently with any number of new types.In the object-oriented programming community, programming using parametric polymorphism is often called generic programming.

3. subtype polymorphism or inclusion polymorphism, a name may denote instances of many different classes as long as they are related by some common super class. objects of different types are entirely substitutable for objects of another type (their base type(s)) and thus can be handled via a common interface.



Ad-hoc polymorphism = function/operator overloading

 ad-hoc polymorphism to refer to polymorphic functions which can be applied to arguments of different types, but which behave differently depending on the type of the argument to which they are applied (also known as function overloading or operator overloading).


Parametric polymorphism = genetics

Parametric polymorphism allows a function or a data type to be written generically, so that it can handle values identically without depending on their type.

class List<T> {
    class Node<T> {
        T elem;
        Node<T> next;
    }
    Node<T> head;
    int length() { ... }
}
 
List map(Func<A,B> f, List<A> xs) {
    ...
}


Subtyping polymorphism ~ abstract class
subtyping polymorphism(sometimes referred to as dynamic polymorphism) allows a function to be written to take an object of a certain type T, but also work correctly if passed an object that belongs to a type S that is a subtype of T.

abstract class Animal {
    String talk();
}
 
class Cat extends Animal {
    String talk() { return "Meow!"; }
}
 
class Dog extends Animal {
    String talk() { return "Woof!"; }
}
 
public class MyClass {
 
    public static void write(Animal a) {
        System.out.println(a.talk());
    }
 
    public static void main() {
        write(new Cat());
        write(new Dog());
    }
 
}


one C++ example:

// dynamic allocation and polymorphism
#include <iostream>
using namespace std;

class CPolygon { // abstract base class
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area (void) =0; // virtual members
    void printarea (void)
      { cout << this->area() << endl; } // pure virtual members can be called from the abstract base class
  };

class CRectangle: public CPolygon {
  public:
    int area (void)
      { return (width * height); }
  };

class CTriangle: public CPolygon {
  public:
    int area (void)
      { return (width * height / 2); }
  };

int main () {
  CPolygon * ppoly1 = new CRectangle; // pointers to base class
  CPolygon * ppoly2 = new CTriangle;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly1->printarea();
  ppoly2->printarea();
  delete ppoly1;
  delete ppoly2;
  return 0;
}


<think>好的,用户现在想了解Python中的多态性(Polymorphism)。首先,我需要回忆一下多态性的基本概念,然后结合用户提供的引用内容来构建回答。用户之前的问题是关于链表remove_first方法的实现,但现在转向了面向对象编程中的多态,这需要我调整思路。 用户提供的引用中,引用[1]提到了animal_sound函数可以接受任何有speak方法的对象,这展示了多态性。引用[3]提到了类的抽象和封装,这可能与多态的实现有关。需要将这些内容整合到回答中,但用户也提到这些引用仅供参考,需要更多参考之前的对话。 在之前的对话中,用户的问题是关于链表操作的实现,其中提到了类的方法和异常处理。这可能与多态中的方法重写有关联,比如不同子类实现相同方法。现在需要将多态的概念与Python的具体实现结合起来,比如使用继承和方法重写。 用户可能需要一个清晰的解释,包括定义、示例代码以及实际应用场景。考虑到用户之前的问题中有代码示例,最好在回答中也提供类似的代码,比如Dog和Cat类继承自Animal,并重写speak方法,然后通过一个函数调用展示多态。 同时,需要解释多态的优点,比如代码的灵活性和可扩展性,引用用户提到的引用内容中的“代码更灵活,适应不同对象”。还要提到鸭子类型,这是Python中多态的重要方面,即关注对象的行为而非类型,比如只要对象有speak方法,就可以调用,而不必强制继承。 可能还需要区分编译型语言的多态和Python的动态多态,强调Python的灵活性。此外,结合引用[3]中的封装和抽象,说明多态如何帮助隐藏实现细节,让用户关注接口而非具体实现。 用户可能想知道如何在实践中应用多态,比如在函数设计时接受接口而非具体类,提高代码的可维护性。此外,可能涉及相关的问题,比如多态与继承的关系,或者多态在设计模式中的应用,比如策略模式。 需要检查是否有遗漏点,比如多态的不同形式(如函数重载和重写),但Python中主要通过重写和鸭子类型实现。确保回答结构清晰,分点解释,有示例代码和相关问题,符合用户之前要求的格式。</think>### Python多态性(Polymorphism)详解 多态性是面向对象编程的三大核心特性之一(封装、继承、多态)。在Python中,多态允许**不同类的对象对同一方法名表现出不同的行为**,且无需在调用时显式检查对象类型。其核心原理是**“接口重用,实现分离”**,通过统一接口调用不同对象的方法,提升代码的灵活性和可扩展性。 --- #### 1. **多态的核心逻辑** - **定义**:多态(Polymorphism)源自希腊语“多种形态”,指**同一操作作用于不同对象时,产生不同的行为结果**。 - **实现基础**: - **继承**:子类继承父类并重写方法。 - **鸭子类型(Duck Typing)**:Python特有的动态类型机制,关注对象的行为(是否具有特定方法),而非对象的类型[^1]。 --- #### 2. **多态的实现示例** 以下通过动物叫声的经典案例演示多态: ```python class Animal: def speak(self): raise NotImplementedError("子类必须实现此方法") class Dog(Animal): def speak(self): # 方法重写 return "Woof!" class Cat(Animal): def speak(self): # 方法重写 return "Meow!" def animal_sound(animal_obj): print(animal_obj.speak()) # 统一调用接口,实际行为由对象类型决定 # 测试多态行为 dog = Dog() cat = Cat() animal_sound(dog) # 输出: Woof! animal_sound(cat) # 输出: Meow! ``` **关键点**: - `animal_sound`函数无需知道具体对象类型,只需确保传入对象有`speak()`方法。 - 通过继承和方法重写,不同子类对同一方法`speak()`表现出不同行为。 --- #### 3. **Python多态的特殊性:鸭子类型** Python的多态不依赖严格的继承关系,而是基于**“如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子”**的理念: ```python class Car: def speak(self): # 非Animal子类,但实现相同方法 return "Vroom!" car = Car() animal_sound(car) # 输出: Vroom! (仍可调用) ``` 此时`Car`类未继承`Animal`,但因实现了`speak()`方法,仍可被`animal_sound`正确处理[^2]。 --- #### 4. **多态的优势** | **优势** | **说明** | |------------------|-------------------------------------------------------------------------| | **代码解耦** | 调用方与具体实现分离,新增子类无需修改调用逻辑。 | | **扩展性** | 添加新类型只需实现相同接口,无需修改已有代码(开闭原则)。 | | **灵活性** | 通过鸭子类型支持非继承关系的对象协作。 | --- #### 5. **多态与抽象类的结合** 通过抽象基类(Abstract Base Class, ABC)强制接口定义,确保多态的安全性: ```python from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius ** 2 class Square(Shape): def __init__(self, side): self.side = side def area(self): return self.side ** 2 def print_area(shape_obj): print(f"Area: {shape_obj.area()}") # 使用示例 circle = Circle(5) square = Square(4) print_area(circle) # 输出: Area: 78.5 print_area(square) # 输出: Area: 16 ``` 通过`ABC`强制子类实现`area()`方法,避免因方法缺失导致的运行时错误[^3]。 --- ### 相关问题 1. **多态与重载(Overloading)有何区别?为什么Python不支持函数重载?** 2. **如何利用多态实现策略模式(Strategy Pattern)?** 3. **在Python中,如何通过`isinstance`检查破坏多态性?应如何避免?** [^1]: 鸭子类型通过行为而非类型实现多态,是Python动态特性的核心体现。 [^2]: 类的封装性隐藏了实现细节,使多态调用仅依赖公共接口。 [^3]: 抽象基类通过`@abstractmethod`强制接口实现,增强多态的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值