什么是多态性,它的用途是什么,如何使用它?


当前回答

在面向对象语言中,多态性允许通过同一个接口处理和处理不同的数据类型。例如,考虑c++中的继承: 类B派生自类A。类型为A*的指针(指向类A的指针)可以用来处理类A的对象和类B的对象。

其他回答

我知道这是一个有很多好答案的老问题,但我想用一句话来回答:

将派生类型视为其基类型。

上面有很多例子可以说明这一点,但我觉得这是一个很好的简明答案。

多态:

这就是面向对象编程的概念。不同对象以自己的方式响应相同消息的能力称为多态性。

多态性源于每个类都存在于自己的名称空间中。在类定义中赋值的名称与在类定义之外赋值的名称不冲突。对象数据结构中的实例变量和对象的方法都是这样:

正如C结构的字段位于受保护的名称空间中一样,因此 对象的实例变量。 方法名也受到保护。与C函数名不同, 方法名不是全局符号。其中一个方法的名称 类不能与其他类中的方法名冲突;两个 非常不同的类可以实现同名的方法。

方法名是对象接口的一部分。当发送请求对象执行某项操作的消息时,该消息命名对象应该执行的方法。因为不同的对象可以具有同名的方法,所以必须相对于接收消息的特定对象来理解消息的含义。发送给两个不同对象的相同消息可以调用两个不同的方法。

多态的主要好处是它简化了编程接口。它允许建立可以在一个又一个类中重用的约定。您不必为添加到程序中的每个新函数都发明一个新名称,而是可以重用相同的名称。编程接口可以被描述为一组抽象行为,与实现它们的类完全不同。

例子:

例1:这是一个用Python 2.x编写的简单示例。

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

例2:多态性在Java中使用方法重载和方法重写概念实现。

让我们以Car为例来讨论多态性。比如福特、本田、丰田、宝马、奔驰等品牌,都是汽车类型。

但每一个都有自己的高级功能和更先进的技术涉及到他们的移动行为。

现在让我们创建一个基本类型Car

Car.java

public class Car {

    int price;
    String name;
    String color;

    public void move(){
    System.out.println("Basic Car move");
    }

}

让我们实现Ford Car的例子。

Ford扩展Car类型以继承其所有成员(属性和方法)。

Ford.java

public class Ford extends Car{
  public void move(){
    System.out.println("Moving with V engine");
  }
}

上面的Ford类扩展了Car类,也实现了move()方法。尽管Ford已经通过继承可以使用move方法,但Ford仍然以自己的方式实现了该方法。这称为方法重写。

Honda.java

public class Honda extends Car{
  public void move(){
    System.out.println("Move with i-VTEC engine");
  }
}

就像Ford一样,Honda也扩展了Car类型,并以自己的方式实现了move方法。

方法重写是启用多态性的一个重要特性。使用方法重写,子类型可以更改通过继承可用的方法的工作方式。

PolymorphismExample.java

public class PolymorphismExample {
  public static void main(String[] args) {
    Car car = new Car();
    Car f = new Ford();
    Car h = new Honda();

    car.move();
    f.move();
    h.move();

  }
}

多态性示例输出:

在PolymorphismExample类的主方法中,我创建了三个对象——Car, Ford和Honda。这三个对象都是由Car类型引用的。

请注意一个重要的一点,超类类型可以引用对象的子类类型,但反之则不可能。原因是父类的所有成员都可以通过继承对子类可用,并且在编译期间,编译器会尝试评估我们正在使用的引用类型是否具有他试图访问的方法。

因此,对于多态例子中的引用car,f和h, move方法存在于car类型中。因此,编译器通过编译过程没有任何问题。

但是当涉及到运行时执行时,虚拟机调用对象上的方法,这些方法是子类型。因此,move()方法从它们各自的实现中调用。

因此,所有对象都是Car类型的,但在运行时,执行取决于调用所发生的对象。这就是所谓的多态性。

在编码术语中,多态性是指您的对象可以通过继承等方式以多种类型存在。如果你创建了一个名为“Shape”的类,它定义了对象的边数,那么你可以创建一个继承它的新类,如“Square”。当你随后创建一个“Square”实例时,你可以根据需要将它从“Shape”前后转换为“Square”。

从理解和应用PHP多态性,感谢Steve Guidetti。

Polymorphism is a long word for a very simple concept. Polymorphism describes a pattern in object oriented programming in which classes have different functionality while sharing a common interface. The beauty of polymorphism is that the code working with the different classes does not need to know which class it is using since they’re all used the same way. A real world analogy for polymorphism is a button. Everyone knows how to use a button: you simply apply pressure to it. What a button “does,” however, depends on what it is connected to and the context in which it is used — but the result does not affect how it is used. If your boss tells you to press a button, you already have all the information needed to perform the task. In the programming world, polymorphism is used to make applications more modular and extensible. Instead of messy conditional statements describing different courses of action, you create interchangeable objects that you select based on your needs. That is the basic goal of polymorphism.

如果你想想这个词的希腊词根,它就会变得很明显。

Poly = many: polygon = many-sided, polystyrene = many苯乙烯(a), polyglot =多种语言,等等。 Morph =变化或形式:形态学=对生物形态的研究,Morpheus =希腊梦之神,可以变成任何形式。

因此,多态性是(在编程中)为不同的底层形式(数据类型)提供相同接口的能力。

例如,在许多语言中,整数和浮点数都是隐式多态的,因为你可以加、减、乘等等,而不管它们的类型是否不同。在通常的术语中,它们很少被视为对象。

但是,以同样的方式,像BigDecimal、Rational或Imaginary这样的类也可以提供这些操作,尽管它们操作的数据类型不同。

典型的例子是Shape类和所有可以从它继承的类(正方形、圆形、十二面体、不规则多边形、splat等等)。

对于多态性,每个类都有不同的底层数据。一个点形状只需要两个坐标(当然假设它是在二维空间中)。圆需要圆心和半径。一个正方形或矩形的左上角和右下角需要两个坐标,(可能)还需要一个旋转。一个不规则的多边形需要一系列的线。

通过使类对其代码和数据负责,您可以实现多态性。在这个例子中,每个类都有自己的Draw()函数,客户端代码可以简单地这样做:

shape.Draw()

为了得到任何形状的正确行为。

这与旧的处理方法相反,旧的方法中代码与数据是分开的,并且您将拥有像drawSquare()和drawCircle()这样的函数。

面向对象、多态和继承都是密切相关的概念,了解它们至关重要。在我漫长的职业生涯中,有许多“银弹”基本上都失败了,但OO范例已经被证明是一个很好的范例。学习它,理解它,爱上它——你会为你所做的感到高兴:)


(a)我最初写这个是作为一个笑话,但它被证明是正确的,因此,并不那么有趣。单体苯乙烯是由碳和氢组成的,C8H8,聚苯乙烯是由(C8H8)n组成的。

也许我应该说明,息肉是字母p的多次出现,尽管现在我必须解释这个笑话,即使这似乎也不好笑。

有时候,你应该在落后的时候就放弃:-)