多态和方法重载

时间:2011-02-10 18:02:23

标签: java polymorphism overloading

我有一个快速而直接的问题:

我有这个简单的课程:

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);
    }
}

UPDATE:实际上是实际调用Number的方法。对此感到抱歉。

如果我调用a.m(null),则使用Number参数调用方法。

我的问题是:这是为什么?这个指定的java语言规范在哪里?

5 个答案:

答案 0 :(得分:26)

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

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

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

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

答案 1 :(得分:12)

  1. 这不是多态或覆盖。这是方法重载
  2. 我对此进行了测试,并且调用了特定方法(而不是m(对象)),并且根据规范始终调用特定方法。 Which overload will get selected for null in Java?

答案 2 :(得分:7)

另一个相关问题供您考虑:

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

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

Number