2016-03-28 77 views
-2

下面是一个示例。将派生对象引用分配给基类变量将不起作用

Class A { 
    Method A(); 
    Method B(); 
    Method C(); 
} 
// A and B are not interfaces 

Class B extends A { 
    Method C(int); 
} 

Class Harness { 
    A ob = new B(); 
    ob.C(3); 
} 

IDE抱怨ob.C(3)不能对方法在C因为AC期望没参数制成。但据我所知,我正在拨打方法CB

据我所知,变量类型决定了被调用的对象的方法集,但是实际的对象决定了将被调用的确切方法。那为什么它不工作?

+0

撇开你的代码是不可编译的......你的类'B'有一个'C'方法。所以调用'new B()。C()'是完全正确的。这不能有任何编译器错误。因此我投票结束不清楚。请编辑您的问题,并提供一个可编辑的示例,正​​确解释您遇到的问题。 – Seelenvirtuose

+0

我编辑了这个问题。请看看它。谢谢。 –

+0

@RajeevSingh *“C可以这样调用ob.C(3);,代码看起来很好”*这是错误的,而'ob.C(3)'''不起作用。 – Tom

回答

3

您已将类型B的对象分配给A类型的变量。 A类别上没有方法C,编译器正在抱怨,因为它必须链接到基于变量声明的类型的方法 - 即A。除非A类型具有某种方法C的声明,否则编译器无法知道在引用A类型时调用该方法是安全的。

+0

是不是它的对象本身将确定将被调用的确切方法? –

+0

只在一定程度上。编译器不允许调用任何*方法 - 只有在变量类型上定义的方法。子类实例*可能*重写一个方法,并且这将是在运行时调用的方法,但方法签名必须为与该变量关联的类型声明。 – sisyphus

0

您已经声明new B是的A和一个实例没有方法C得到它的工作,你沃尔德必须重新至少投出您ob它B.所以assumig这是一个伪代码,这会工作:

A ob=new B(); 
    ((B)ob).C(); 
+0

我在类B中调用方法C(int a)而不是类A中的方法。 –

+0

在你的情况中,尽管事实上'ob'确实是'B'类的实例,你将它声明为'A的实例'所以你只能访问'A'类型的方法和字段。要到达'B'成员,必须明确地将你的'ob'强制转换(“重新声明”)为'B'类。这很简单。 – Antoniossss

+0

这是有道理的。谢谢。 –

2

正如您在您的问题本身中提到的那样,变量的类型决定了可以使用它调用的所有方法。在你的例子中,class A没有签名为C(int)的方法。它只有一个签名为C()的方法。所以,B中的方法C(int)甚至不是重写的方法。这是一种重载的方法。

运行时多态仅适用于重写的方法。

您必须让class AC(int)方法才能成功编译此代码。

相关问题