在继承中观察到奇怪的行为

时间:2014-07-31 14:01:50

标签: java inheritance

我有一个界面 IfcBase ,由另一个类 Base 实现。此类进一步扩展为第二类 SubBase 。进一步的SubBase类实现另一个接口 IfcNew 。这两个接口都声明了具有相同签名的方法。现在SubBase没有定义IfcNew的方法。我现在创建一个SubBase实例并将其分配给引用类型IfcNew。然后我调用单独的方法并获得输出。在这种情况下执行IfcBase的方法。我相信在编译或执行期间,不应该在某个阶段允许这样做。我无法理解这种行为并寻求帮助。来源如下。非常感谢!

public interface IfcBase
{
    public void printString();
}

public class Base implements IfcBase
{
    public void printString()
    {
        System.out.println("Base Class");
    }
}

public interface IfcNew
{
    public void printString();
}

public class SubBase extends Base implements IfcNew
{
    //
}

public class Test
{
    public static void main(String[] args)
    {
        IfcNew i = new SubBase(); 
        i.printString();  //Output:Base Class
    }
}

3 个答案:

答案 0 :(得分:2)

这是继承在Java中的工作方式。

您在public void printString()中实施了一个名为Base的方法,您可以从中扩展SubBase。因此,此实现将在此类中隐式提供。

对于implements IfcNew声明中的SubBase部分,编译器将仅检查SubBase是否实现了与public void printString()具有相同签名的方法。由于它从Base隐式继承了这个实现,所以没有什么可抱怨的。

如果从OO设计的角度来看,可以很容易地理解这种行为。请看一下我几年前写的this article。查看名为方法签名,对象接口,类型,子类型和超类型的部分。根据{{​​1}}的定义,subtype已经是SubBase的子类型,因此编译器没有问题。

答案 1 :(得分:1)

这是Java中继承的正确行为。

使用相同签名方法实现多个接口时没有警告,因为解析在运行时进行。

在这种情况下,您的SubBase课程不需要像其父级一样实施printString,即使它不是"相同的" printString:相同的签名允许在运行时解析。

答案 2 :(得分:0)

这很明显也不奇怪。这是因为具有相同签名的方法已经在基类中实现,并且当您扩展基类时,它会自动继承。现在,当您尝试将对象分配给IfcNew引用时,调用实现的方法,该方法在子类中不被覆盖,这意味着调用基类方法实际上是IfcBase的实现。