【问题标题】:Polymorphism and method overloading多态性和方法重载
【发布时间】:2011-06-25 01:22:32
【问题描述】:

我有一个简单直接的问题:

我有这个简单的课程:

public class A
{
    public void m(Object o)
    {
      System.out.println("m with Object called");
    }

    public void m(Number n)
    {
       System.out.println("m with Number called");
    }
    public static void main(String[] args)
    {
       A a = new A();
       // why will m(Number) be called?
       a.m(null);
    }
}

更新:实际上是实际调用 Number 的方法。很抱歉造成混乱。

如果我调用 a.m(null) 它会调用带有 Number 参数的方法。

我的问题是:为什么会这样?这是在 java 语言规范中的什么地方指定的?

【问题讨论】:

  • ... 因为null 不是Number 对象,所以属于更广义的Object 桶。
  • 这很有趣,因为在我的机器上(在 Eclipse 上运行)它总是默认为 Number 方法
  • -1 这是重载,而不是覆盖

标签: java polymorphism overloading


【解决方案1】:

首先,它实际上调用了m(Number)

发生这种情况是因为这两种方法都适用,但m(Number)最具体的方法,因为m(Number)的任何参数都可以传递给m(Object),但反之亦然。

如果将m(Object) 替换为m(String)(或添加其他方法,例如m(Date)),编译器会报告歧义,因为无法识别最具体的方法。

请参阅 Java 规范中的 Choosing the Most Specific Method 部分。

【讨论】:

  • 好的,现在我已经实际运行了示例代码,我也看到了这一点。这也是有道理的,一旦我添加了 m(Date n){...} 我得到了一个错误:“方法 m(Object) 对于类型来说是不明确的”
【解决方案2】:
  1. 这不是多态性或覆盖。这是方法重载
  2. 我对此进行了测试,并且正在调用特定方法(不是 m(Object)),并且根据规范,始终调用特定方法。 Which overload will get selected for null in Java?

【讨论】:

  • +1 用于注意覆盖和重载之间的区别
【解决方案3】:

您需要考虑的另一个相关问题:

public static void main(String[] args)
{
   A a = new A();
   Object n = new Integer(1);
   a.m(n); // which method will be called?
}

【讨论】:

  • "m with Object called" 将被调用,但我不知道为什么。谁能解释一下?直觉上,我认为“m with Number called”会被打印出来,但是......不。
【解决方案4】:

我的 2 美分。带有 Number 参数的方法是被调用的方法,因为 Number 扩展了 Object。过去我也遇到过类似的情况,我确实重写了一个方法并将 Component 而不是 JComponent (错误地)。我花了一周的时间才找出我的方法从未被调用的原因。我想通了,如果重载方法之间存在某种继承关系,那么 JVM 会首先匹配类层次结构中较深的方法。

【讨论】:

    【解决方案5】:

    Object 是 Java 中的默认类型。如果将m(Object o) 方法重构为m(String o),则会出现编译时错误,指出调用m(null) 不明确,因为Java 无法确定StringNumber 之间的哪个类默认为null

    除此之外,在m(Object o)m(Number o) 之间,调用m(null) 将调用m(Number o),因为它是最专业的方法。否则,您需要将null 转换为Object(或任何不是Number 的实例)。

    a.m((String) null);
    

    【讨论】:

    • null 没有类型,它调用 m(Number)
    • 好吧...正式地有一个空类型,它是所有引用类型的子类型。很奇怪。
    猜你喜欢
    • 2011-06-22
    • 2017-06-06
    • 1970-01-01
    • 2010-11-14
    • 2011-10-15
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多