多态性:多态参考的目的

时间:2018-02-20 22:43:30

标签: oop polymorphism

例如:

class RuntimePolymorphismDemo {

  public static void main(String[] args) {
    Animal ref1 = new Animal();
    Animal ref2 = new Dog();
    Animal ref3 = new Cow();
    Animal ref4 = new Snake();
    ref1.whoAmI();
    ref2.whoAmI();
    ref3.whoAmI();
    ref4.whoAmI();
  }
}

如果您可以像这样定义它们,那么定义类型为Animal的ref1,ref2,ref3和ref4变量的目的是什么:

    Animal ref1 = new Animal();
    Dog ref2 = new Dog();
    Cow ref3 = new Cow();
    Snake ref4 = new Snake();

你可以直接调用whoAmI()方法吗? 你使用父类获得了什么?

感谢。

2 个答案:

答案 0 :(得分:1)

在您引用的示例的上下文中看起来是有效且合理的。回到运行时ploymorphism的基本定义是" 相同的界面但不同的实现 "

所以在你的例子中:Animal基本上为你提供了一个界面whoAmI()。但是,您将获得Animal指向的实际类型的行为(这称为运行时调度或动态调度),具体取决于该类型的具体实现:

ref2.whoAmI(); /* will say I am Dog */
ref3.whoAmI(); /* will say I am snake*/

这种行为的重点是什么:这是OOP最重要的概念之一,它可以促进封装。

例如:你可能有一个方法可以做很多事情。它将显示动物名称,动物图片和历史。让我们说该方法看起来像:

public void ShowAnimalInfo(Animal animal)
{

   animal.WhoAmI();
   var picture = animal.GetImage();
   var history = animal.GetHistory();
   /* statement and logic to process picture and history on some UI */
}

现在,此方法的使用者可以使用以下方法:

ShowAnimalInfo(new Dog()); /*OR*/
ShowAnimalInfo(new Cow());

如果你注意到,你的方法ShowAnimalInfo()是从实际的动物中抽象出来的,可以通过只使用Animal提供的接口来重新使用,让运行时负责调用实际的实现。

答案 1 :(得分:0)

OOP的全部目的是必须隐藏对象的实现,因此在严格的OOP样式中,当我们使用对象时,我们关心它的协议(接口)以及何时构造我们关心它的实现的对象,赋予它特殊的特性。所以正确的OOP风格是第一个:

Animal ref2 = new Dog();

实例化后,没有'狗'概念,只是一个'动物'。这种误解的产生是因为在大多数现代OOP语言中,Class也可以是Type,但这些实际上是不同的概念。另见这个问题:Object-oriented languages without class concept