重载和重载方法中的多态性 [英] Polymorphism in Overloaded and Overridden Methods

查看:94
本文介绍了重载和重载方法中的多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们来看看这个简单的Java代码:

Let's take this simple Java code:

public class Animal {
  public void eat() {
    System.out.println("Generic Animal Eating Generically");
   }
}

public class Horse extends Animal {
  public void eat() {
    System.out.println("Horse eating hay ");
  }

  public void eat(String s) {
    System.out.println("Horse eating " + s);
  }
}

我正在试图找出哪个版本的将运行三个eat()方法。现在,当我输入

I'm trying to figure out which version of the three eat() methods will run. Now, when I type

Animal a = new Animal();
a.eat();

输出是Generic Animal Eating Generically,这是完全可以理解的。

The output is "Generic Animal Eating Generically", which is completely understandable.

输入时会发生同样的事情:

The same thing happens when I type:

Horse h = new Horse();
h.eat();

输出是马吃干草,这又是完全合乎逻辑的。

The output is "Horse eating hay", which is, again, completely logical.

虽然这对我来说很困惑。当我输入:

Here's where it gets confusing for me though. When I type:

Animal ah = new Horse();
ah.eat();

我得到:

Horse eating hay

我希望编译器从中调用eat()方法Animal类引用,而不是Horse对象引用。

I expected the compiler to invoke the eat() method from the Animal class reference, not the Horse object reference.

所以我的问题是,当我有一个通用引用变量
类型引用一个对象时,我怎么能确定编译器将调用哪个方法?类型(如下所示:动物马=新马();

So my question is, how can I know for sure which method the compiler is going to invoke when I have a generic reference variable types referring to an object type (like this one: Animal horse = new Horse();

推荐答案


我期待编译器从Animal类引用调用eat()方法,而不是Horse对象引用。

I expected the compiler to invoke the eat() method from the Animal class reference, not the Horse object reference.

让我们先修正这个语句。 Animal 类型的引用,语句 new Horse()创建一个 Horse 类型的实例,并将其分配给 Animal 引用。

Let's correct this statement first. The variable ah is a reference of type Animal and the statement new Horse() creates an instance of type Horse and assigns it to an Animal reference.

现在术语已经清楚,这种行为是预期的,被称为runtype-polymorphism或动态方法调度。在编译时, eat()是基于 Animal 类型的引用类型解析的,但在运行时,方法是at将被调用基于实例类型, Horse

Now that the terminologies are clear, this behavior is expected and is termed as runtype-polymorphism or dynamic method dispatch. At compile time, eat() is resolved based on the reference type which is of type Animal, but at runtime, the method that will be called is based on the instance type which is Horse.


当我有一个引用对象类型的泛型引用变量类型时,我怎么能确定编译器将调用哪个方法

how can I know for sure which method the compiler is going to invoke when I have a generic reference variable types referring to an object type

您可以按照以下简单步骤操作:

You could follow these simple steps :


  1. 检查被调用的方法。 ah.eat()正在调用方法 eat

  2. 查看父类和子类中是否存在具有完全相同签名的方法(返回类型协方差除外)。 (方法是否覆盖?)

  3. 检查引用类型。在 Animal ah = new Horse()中,引用类型为 Animal 即父类

  4. 检查实例类型。在 Animal ah = new Horse()中,实例类型为 Horse ,这是子类。

  1. Check the method being called. ah.eat() is calling the method eat.
  2. See if a method with the exact same signature (with the exception being return type covariance) is present in both the parent and child class. (method overriden or not?)
  3. Check the reference type. In Animal ah = new Horse(), the reference type is Animal that is the parent class
  4. Check the instance type. In Animal ah = new Horse(), the instance type is Horse which is the child class.

如果满足上述所有条件,您将看到runtype多态,并且将调用子类中的方法。在任何其他场景中,将根据引用类型解析要调用的方法。

If all the above conditions are satisfied, you are looking at runtype polymorphism and the method from the child class will be called. In any other scenario, the method to be called will be resolved based on the reference type.

还需要了解子类从其父级继承方法。假设您从 Horse 类中删除 public void eat()方法,您不再 Overrding eat()方法;但是, Horse 中的 public void eat(String s)方法仍被称为重载 Animal 中继承的 eat 方法。接下来,让我们在 Animal 中添加 public void eat(String s)方法。通过此添加,您现在 Animal 中重载 eat 方法在 Horse 类中覆盖。无论您如何更改代码,上述4个步骤将始终帮助您确定将调用哪个方法。

It would also pay to understand that a child class inherits methods from its parents. Lets say that you delete the public void eat() method from Horse class, you are no longer Overrding the eat() method; however, the public void eat(String s) method in Horse is still said to Overload the inherited eat method from Animal. Next, lets add a public void eat(String s) method in Animal. With this addition, you are now Overloading the eat method in Animal and Overrding it in Horse class. No matter how you change the code, the 4 steps mentioned above will always help you decide which method will be called.

这篇关于重载和重载方法中的多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆