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


当前回答

OOP中的多态性意味着一个类可以有不同的类型,继承是实现多态性的一种方式。

for example, Shape is an interface, it has Square, Circle, Diamond subtypes. now you have a Square object, you can upcasting Square to Shape automatically, because Square is a Shape. But when you try to downcasting Shape to Square, you must do explicit type casting, because you can't say Shape is Square, it could be Circle as well. so you need manually cast it with code like Square s = (Square)shape, what if the shape is Circle, you will get java.lang.ClassCastException, because Circle is not Square.

其他回答

我正在浏览另一篇完全不同的文章。多态性出现了……现在我认为我知道多态性是什么....但显然不是用这种美丽的方式解释的。想把它写在某个地方。更好的是分享它…)

http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife

从这部分开始阅读:

…多态性。这是一种很奇怪的说法,不同的名词可以有相同的动词。

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

多态:

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

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

正如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类型的,但在运行时,执行取决于调用所发生的对象。这就是所谓的多态性。

通常这指的是A类型对象的行为与b类型对象相似的能力。在面向对象编程中,这通常是通过继承来实现的。一些维基百科的链接来阅读更多:

面向对象编程中的多态性 类型多态性

编辑:固定破碎的链接。

多态是指您可以将对象视为某个对象的通用版本,但当您访问它时,代码将确定它的确切类型并调用相关代码。

下面是一个c#的例子。在控制台应用程序中创建四个类:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

现在在控制台应用程序模块的Main()中创建以下内容:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

在这个例子中,我们创建了一个基类Vehicle的列表,它不知道它的每个子类有多少个轮子,但是知道每个子类负责知道它有多少个轮子。

然后我们将自行车、汽车和卡车添加到列表中。

接下来,我们可以循环遍历列表中的每个Vehicle,并将它们都视为相同的,但是当我们访问每个Vehicles 'Wheels'属性时,Vehicle类将该代码的执行委托给相关的子类。

该代码被称为多态代码,因为执行的确切代码是由在运行时引用的子类决定的。

我希望这对你有所帮助。