为啥编译器会自动转换而不进一步继承?

Posted

技术标签:

【中文标题】为啥编译器会自动转换而不进一步继承?【英文标题】:Why does the compiler cast automatically without going further in the inheritance?为什么编译器会自动转换而不进一步继承? 【发布时间】:2013-10-07 09:32:27 【问题描述】:

当我尝试运行以下代码 sn-p 时,它执行了错误的重载方法。我很困惑为什么会这样? [testB.TestMethod(testValue)方法执行public double TestMethod(double value)方法]

public class TestA

    public int TestMethod(int value)
    
        return value;
    


public class TestB : TestA

    public double TestMethod(double value)
    
        return value;
    


static void Main( string[] args )

    TestB testB = new TestB();

    int testValue = 3;

    testB.TestMethod(testValue);

你对此有什么想法吗?

有没有什么方法可以通过TestB实例调用TestA类方法而不强制转换为TestA?

但这在 JAVA 和 C++ 中不会发生

【问题讨论】:

【参考方案1】:

继承

继承会导致混乱的效果。当编译器运行时 寻找实例方法重载,它考虑编译时间 调用“目标”的类,并查看声明的方法 那里。如果它找不到合适的东西,它会查看父级 类...然后是祖父母类等。这意味着如果有 层次结构不同级别的两种方法,“更深”的一种 将首先被选中,即使它不是“更好的功能成员” 来电。

来源:http://csharpindepth.com/Articles/General/Overloading.aspx

【讨论】:

所以如果你想调用TestA上具有隐式兼容类型的同名成员,你必须转换为TestA @Charleh,是的,如果你想调用TestA 中的重载,你必须将它转换为TestA。我测试过了。 你的意思是不强制转换就不能调用TestA类方法ryt吗? 没错,否则我会实现它,比如首先寻找完全匹配,然后寻找最适用的匹配到父类。【参考方案2】:

根据规范,在“过载解决方案”下:

...如果派生类中的任何方法适用(第 7.6.5.1 节),则基类中的方法不是候选方法。

【讨论】:

即使你在TestA virtualoverride 中创建了TestB 中的重载方法,这种情况仍然会发生。 @JeppeStigNielsen 实际上,紧接在上面的词(在“...”中)是:“...方法调用的候选集不包括标记为覆盖的方法(第 7.4 节) ),"

以上是关于为啥编译器会自动转换而不进一步继承?的主要内容,如果未能解决你的问题,请参考以下文章

201671010145 2016-2017《Java程序设计》Java接口的功能

java中子类继承了父类就可以使用父类的方法了,那为啥还要用super?

java中子类继承了父类就可以使用父类的方法了,那为啥还要用super?

为啥我们在 Java 中使用自动装箱和拆箱?

idea自动编译scss为啥会生成.map

为啥函数体在结构中编译,而不是在特征中?