多态多义性区别是如何工作的? [英] How does polymorph ambiguity distinction work?

查看:112
本文介绍了多态多义性区别是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于我有一个带有两个构造函数的类:

Given I have a class with two constructors:

public class TestClass {
    ObjectOne o1;
    ObjectTwo o2;

    public TestClass(ObjectOne o1) {
        // ..
    }

    public TestClass(ObjectTwo o2) {
        // ..
    }
}

请假定ObjectOneinterface类型,并且是ObjectTwo implements ObjectOne.如果我打电话,会发生什么事?

Please assume, that ObjectOne is an interface type, and ObjectTwo implements ObjectOne. What happens, if I call:

new TestClass(null);

如何确定正确的调用方法?谁来决定呢? Java和其他OOP语言之间有区别吗?

How to determine the correct method to call? And who determines that? Are there differences between Java and other OOP languages?

推荐答案

这个问题实际上是关于解决模棱两可的重载,而不是关于运行时多态性(因为选择要调用的重载方法是在 compile-时间).

This question is really about resolving ambiguous overloads, and not really about run-time polymorphism (because choosing which overloaded method to invoke is done at compile-time).

方法解析是一件很复杂的事情,在这种情况下,代码是否完全编译取决于所涉及的类型. 在很多情况下,代码都可以编译.请参见下面的代码(请注意String implements CharSequence):

Method resolution is a complicated thing, and in this case, whether or not the code compiles at all does depend on what the types involved are. There are plenty of situations in which the code will compile. See code below (note that String implements CharSequence):

public class MyClass {
    MyClass(CharSequence charSeq) {
        System.out.println("CharSequence");
    }
    MyClass(String s) {
        System.out.println("String");
    }   
    public static void main(String[] args) {
        new MyClass(null); // prints "String"
        new MyClass(""); // prints "String"
        new MyClass((CharSequence) null); // prints "CharSequence"
        new MyClass((CharSequence) "");   // prints "CharSequence"
    }
}

请注意,如果不进行强制类型转换,则会选择String重载.这与JLS中指定的完全相同:

Note that without the cast, the String overload is chosen. This is exactly as specified in JLS:

如果有多个成员方法可以访问并且适用于方法调用,则必须选择一个成员方法来提供运行时方法分派的描述符. Java编程语言使用选择最具体的方法的规则.

A String是-a CharSequence,但不是所有的CharSequence是-a String.因此,StringCharSequence更具体 ,因此为什么在上面的示例中选择了String重载.

A String is-a CharSequence, but not all CharSequence is-a String. Therefore, String is more specific than CharSequence, hence why the String overload is chosen in the above example.

值得注意的是,这个确切的问题(本质上)出现在精彩的> em> Java Puzzlers (强烈推荐),特别是益智46:令人困惑的构造函数的情况

It is worth noting that this exact question (in essence) appeared in the wonderful Java Puzzlers (highly recommended), specifically Puzzle 46: The Case of the Confusing Constructor

Java的重载解决过程分为两个阶段.第一阶段选择所有可访问和适用的方法或构造函数.第二阶段选择在第一阶段中选择的最具体的方法或构造函数.如果一个方法或构造函数可以接受传递给另一个的任何参数

Java's overload resolution process operates in two phases. The first phase selects all the methods or constructors that are accessible and applicable. The second phase selects the most specific of the methods or constructors selected in the first phase. One method or constructor is less specific than another if it can accept any parameters passed to the other

理解这个难题的关键是,最特定于方法或构造函数的测试不使用实际参数 :调用中出现的参数.它们仅用于确定适用的过载.编译器确定了哪些重载适用并可以访问后,便仅使用形式参数:声明中出现的参数来选择最具体的重载.

The key to understanding this puzzle is that the test for which method or constructor is most specific does not use the actual parameters: the parameters appearing in the invocation. They are used only to determine which overloadings are applicable. Once the compiler determines which overloadings are applicable and accessible, it selects the most specific overloading, using only the formal parameters: the parameters appearing in the declaration.


我将用有效的Java 2nd Edition 的引号结尾,项目41:明智地使用重载:


I will close with a quote from Effective Java 2nd Edition, Item 41: Use overloading judiciously:

确定选择哪个重载的规则非常复杂.他们占据了语言规范中的 33 页,并且很少有程序员能够理解他们所有的细微之处.

The rules that determine which overloading is selected are extremely complex. They take up thirty-three pages in the language specification, and few programmers understand all of their subtleties.

不用说,这本书也是强烈推荐.

  • Polymorphism vs Overriding vs Overloading
  • Method Overloading. Can you overuse it?

这篇关于多态多义性区别是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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