多态性和方法重载
Posted
技术标签:
【中文标题】多态性和方法重载【英文标题】: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 这是重载,而不是覆盖
【参考方案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】:-
这不是多态性或覆盖。这是方法重载。
我对此进行了测试,并且正在调用特定方法(不是 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 无法确定String
和Number
之间的哪个类默认为null
除此之外,在m(Object o)
和m(Number o)
之间,调用m(null)
将调用m(Number o)
,因为它是最专业的方法。否则,您需要将null
转换为Object
(或任何不是Number
的实例)。
a.m((String) null);
【讨论】:
null 没有类型,它调用 m(Number) 好吧...正式地有一个空类型,它是所有引用类型的子类型。很奇怪。以上是关于多态性和方法重载的主要内容,如果未能解决你的问题,请参考以下文章