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。