java Java重载和继承规则

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11110631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:51:08  来源:igfitidea点击:

Java overloading and inheritance rules

javainheritanceoverloading

提问by Lugaid

I've been studying because I have an exam and I don't have many problems with most of Java but I stumbled upon a rule I can't explain. Here's a code fragment:

我一直在学习,因为我有考试,而且我在大多数 Java 方面没有太多问题,但我偶然发现了一个我无法解释的规则。这是一个代码片段:

public class A {

    public int method(Object o) {
        return 1;
    }

    public int method(A a) {
        return 2;
    }
}

public class AX extends A {

    public int method(A a) {
        return 3;
    }

    public int method(AX ax) {
        return 4;
    }
}

public static void main(String[] args) {
    Object o = new A();
    A a1 = new A();
    A a2 = new AX();
    AX ax = new AX();

    System.out.println(a1.method(o));
    System.out.println(a2.method(a1));
    System.out.println(a2.method(o));
    System.out.println(a2.method(ax));
}

This returns:

这将返回:

1 3 1 3

1 3 1 3

While I would expect it to return:

虽然我希望它返回:

1 3 1 4

1 3 1 4

Why is it that the type of a2 determines which method is called in AX?

为什么是a2的类型决定了AX中调用的是哪个方法?

I've been reading on overloading rules and inheritance but this seems obscure enough that I haven't been able to find the exact rule. Any help would be greatly appreciated.

我一直在阅读有关重载规则和继承的内容,但这似乎很模糊,以至于我无法找到确切的规则。任何帮助将不胜感激。

采纳答案by Perception

The behavior of these method calls is dictated and described by the Java Language Specification(reference section 8.4.9).

这些方法调用的行为由Java 语言规范(参考第 8.4.9 节)规定和描述。

When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4).

调用方法时(第 15.12 节),在编译时使用实际参数(和任何显式类型参数)的数量和参数的编译时类型来确定将被调用的方法的签名(第 15.12.2 节)。如果要调用的方法是实例方法,则将在运行时使用动态方法查找(第 15.12.4 节)确定要调用的实际方法。

In your example, the Java compiler determines the closest match on the compile type of the instance you are invoking your method on. In this case:

在您的示例中,Java 编译器确定您调用方法的实例的编译类型的最接近匹配。在这种情况下:

A.method(AX)

The closest method is from type A, with signature A.method(A). At runtime, dynamic dispatch is performed on the actualtype of A (which is an instance of AX), and hence this is the method that is actually called:

最接近的方法来自类型 A,带有签名A.method(A)。在运行时,动态分派是在A的实际类型(它是 AX 的实例)上执行的,因此这是实际调用的方法:

AX.method(A)

回答by Sam

I will clarified it in more simple way. See when you making sub class object with super class reference like here you did.

我会用更简单的方式来澄清它。看看你什么时候用超类引用制作子类对象,就像你在这里所做的那样。

Always one thing keep in your mind that when you call with super class reference, no matters object is of sub class it will go to the super class, check method with this name along with proper signature is there or not.

始终记住一件事,当您使用超类引用调用时,无论对象是否属于子类,它都会转到超类,检查具有此名称的方法以及正确的签名是否存在。

now if it will find it, than it will check whether it is overridden?? if yes than it will go to the sub class method like here it went. another wise it will execute the same super class method.

现在如果它会找到它,它会检查它是否被覆盖?如果是,那么它会像这里那样转到子类方法。另一个明智的做法是执行相同的超类方法。

I can give you the example of it...just hide

我可以给你举个例子......隐藏起来

public int method(A a) {
        return 3;
    }

method & check your answer you will get 1 2 1 2, why because it gives first priority to reference. because you overridden it & than calling it, so its giving 3..!! hope its big but easy to understand. Happy Learning

方法&检查你的答案你会得到1 2 1 2,为什么因为它优先参考。因为你覆盖了它而不是调用它,所以它给了 3..!! 希望它很大但很容易理解。快乐学习

回答by Lakatos Gyula

a2 referenced as an A and the JVM using the reference first (not the acutal object as you expected).

a2 被引用为 A 并且 JVM 首先使用引用(而不是您预期的实际对象)。