Java 将派生对象引用指定给基类的变量won';行不通
这里有一个例子Java 将派生对象引用指定给基类的变量won';行不通,java,Java,这里有一个例子 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)不能用于A中的方法C,因为C不需要任何参数。但据我所知,我正在B中调用方法C 据我
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)
不能用于A
中的方法C
,因为C
不需要任何参数。但据我所知,我正在B
中调用方法C
据我所知,变量类型决定了要调用的方法集,方法集的引用被分配给了对象,但实际对象决定了要调用的确切方法。那么为什么它不起作用呢 您已将
B
类型的对象分配给a
类型的变量。类A
上没有方法C
,编译器正在抱怨,因为它必须链接到基于变量声明类型的方法,即A
。除非类型A
具有方法C
的某种声明,否则编译器无法知道在引用A
类型时调用该方法是安全的。您已声明新B
为A
的实例,而A没有方法C
使其工作至少必须再次施放你的ob
it B。因此假设这是一个伪代码,这将起作用:
A ob=new B ();
((B)ob).C ();
正如您在问题中提到的,变量的类型决定了可以使用它调用的所有方法。在您的示例中,
class A
没有签名为C(int)
的方法。它只有一个签名为C()
的方法。因此,B中的方法C(int)
甚至不是被重写的方法。这是一个重载方法
运行时多态性仅适用于重写的方法
要成功编译此代码,您必须使用
class A
方法才能使用C(int)
方法。将代码不可编译放在一边。。。在你的班上有一个方法C
。因此,调用newb().C()
完全可以。这不可能有任何编译器错误。因此,我投票决定以不清楚的方式结束。请编辑您的问题,并提供一个可编译的示例,准确解释您的问题。我已编辑了问题。请看一看。谢谢。@RajeevSingh“C可以像这样被称为ob.C(3);,代码看起来不错”这是错误的,ob.C(3)代码>不起作用。@rajeevsing不,不起作用。只要ob
具有声明的类型A
并且A
没有方法C(int)
它就不会工作。@Tom。是 啊我很感激对象本身会决定调用的确切方法,只是在某种程度上。编译器不允许调用任何方法-只调用在变量类型上定义的方法。子类实例可能会重写一个方法,这就是在运行时调用的方法,但必须为与变量关联的类型声明方法签名。我在类B中调用方法C(int A),而不是类A中的方法。在您的情况下,尽管ob
确实是B
类的实例,您将其声明为A
的实例,因此您只能访问A
类型中的方法和字段。要访问B
成员,您必须明确地将ob
转换为B
类(“重新声明”)。就这么简单,这是有道理的。谢谢。现在您需要将int
传递到方法调用中,因此值得转换到B
:D。