基类设置为派生类,不能在派生类中调用方法?

时间:2014-02-06 11:09:59

标签: c# java oop object

对于那些不支持从多个类继承的语言(不确定这里是否重要,只是认为我会详细说明),这是一个普遍的OOP问题,如Java:

好的,你有基类:

class Base {}

class Derived extends Base
{
   SomeMethod(){}
}

Main()
{
    Base baseInstance = new Base();
    Derived derivedInstance = new Derived();

    baseInstance = derivedInstance;

    baseInstance.someMethod();            <<<<<< this does not work. why?

}

为什么在将baseInstance设置为derivedInstance时,是否无法调用Derived类中定义的方法?

由于您将baseInstance设置为derivedInstance,您是否可以访问此方法?

3 个答案:

答案 0 :(得分:6)

作为基类输入的变量不能设定有关子类的方法。例如,对于所有编译器都知道,baseInstance可以保留对BaseSomeOtherClass extends Base的引用。现在,您可以说在这种情况下编译器可以解决它,但是:不是编译器做的。编译器的规则很简单:如果您输入的变量为Base,则只能使用Base上已知的内容。

如果你想使用特定子类的专门方法,那么你需要让编译器执行带类型检查的强制转换,即

Derived special = (Derived)baseInstance; // I'm using C# syntax here,
special.someMethod();                    // but should be similar or identical

答案 1 :(得分:1)

这一行

baseInstance = derivedInstance;

未将baseInstance设置为Derived类型。它仍然是Base类型。

如果someMethod()Base中定义的方法,则只能在someMethod类型的对象上调用Base。编译器知道更多派生方法。

答案 2 :(得分:1)

在java 实例是在运行时创建,因此实际的类实例在运行时得到解析,而不是在编译期间解析。

因此,编译器始终查看引用类型以确定引用变量可以引用哪些方法或成员。

在您的情况下,baseInstance = derivedInstance;即使被引用的实际类是Base的子类,编译器也只是假设它是Base类型。显然,Base类没有someMethod();,因此它不允许您调用它。

作为一种解决方法,你可以试试这个:

if(base instanceof Derived) {
 // Downcast it before calling
 ((Derived)baseInstance).someMethod(); 
}