使用super作为引用类型时,无法访问子类中的方法

时间:2017-01-24 21:23:05

标签: java inheritance polymorphism

我有一个问题,我有一些课说

 public class Foo {

   public Foo() {
    // Do stuff
   }

   public void generalMethod() {
      //to general stuff
   }

 }

 public class Bar extends Foo {

     public Bar() {
        //do stuff
     }

     public void uniqueMethod() {
        //do stuff
     }
 }


 public class Driver() {
    public static void main(String[] args) {
       Foo test = new Bar();

       test.uniqueMethod(); //this causes an error
    }
 }

所以我得到一个错误,说明方法uniqueMethod()未定义为Foo,但是当我将赋值更改为Bar test = new Bar();时问题就消失了。我不明白,因为它应该与Foo test = new Bar();

一起使用

有人可以说明出现此错误的原因吗?

提前谢谢。

3 个答案:

答案 0 :(得分:2)

虽然该方法在运行时存在,但编译器只看到类型test的对象Foo没有方法uniqueMethod。 Java使用虚方法,其中将调用的方法在runtime确定。因此,编译器再次看不到此特定实例的类型是Bar。如果你真的需要调用该方法,你可以进行强制转换并调用方法:

((Bar)test).uniqueMethod();

现在,对于编译器,您的类型为Bar,他可以看到Bar类型

中可用的所有方法

像编译器和JVM一样思考

示例1

Foo test = new Bar();

所以,我有一个类型为Foo的变量。我必须验证对此类成员的所有后续调用是否正常 - 它将查找Foo类中的所有成员,编译器甚至不查找实例类型。

runtime中,JVM将知道我们有一个Foo类型的变量,但实例类型为Bar。这里唯一的区别是它(JVM)将查看实例以使virtual calls成为方法。

示例2

Bar test = new Bar();

所以,我有一个Bar类型的变量。我必须验证对此类成员的所有后续调用是否正常 - 它将查找Foo和' Bar'中的所有成员。类,编译器,甚至不会查找实例类型。

runtime中,JVM将知道我们有一个Bar类型的变量,以及一个相同类型的实例:Foo。现在我们再次访问FooBar类中定义的所有成员。

答案 1 :(得分:2)

使用后期绑定你必须在超级类中使用相同的方法" Fathor" ,否则它将无法工作!

这项工作与我合作

//

public  class foo {
public void print(){
System.out.println("Super,"+2);}

}

类bo扩展foo {

    public void print(){
        System.out.println("Sup,"+9);
        }

}

测试//

公共抽象类测试{

public static void main(String[] args) {
    // TODO Auto-generated method stub

     foo t = new bo();
     t.print();
}

} ///

输出

燮,9

答案 2 :(得分:1)

发生此错误是因为编译器不知道test的类型为Bar,它只知道Foo的声明类型。

public void test(Foo foo) {
        // error! this method can accept any variable of type foo, now imagine if you passed it 
        // another class that extends Foo but didnt have the uniqueMethod. This just wont work
        foo.uniqueMethod(); 
    }