【问题标题】:Can't access methods in sub class when using the super as the reference type使用 super 作为引用类型时无法访问子类中的方法
【发布时间】:2017-01-24 21:23:05
【问题描述】:

我有一个问题,我有一些班级说

 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();

有人可以提出这个错误发生的原因吗?

提前谢谢你。

【问题讨论】:

  • 为什么它应该与Foo一起使用?该类中没有这样的方法。
  • 因为 Foo 是父类,JVM 不应该查看 uniqueMethod() 的子类,因为它不在父类 (Foo) 中
  • JVM 在这里无关紧要。编译器在工作,他只查看定义的变量类型。多态(你的意思)发生在运行时,而不是编译时
  • 它适用于声明的类型,即您在变量名之前定义的类型,而不是在运行时分配给它的类型。

标签: java inheritance polymorphism


【解决方案1】:

虽然该方法在运行时存在,但编译器只看到Foo 类型的对象test 没有方法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”类中的所有成员,编译器甚至不查找实例类型。 p>

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

【讨论】:

  • 感谢您分享((Bar)test).uniqueMethod(); 的语法。我知道能够通过将对象转换为具有声明的子类型(如Bar actualBar = (Bar) test;)的新变量来将对象视为子类,因为(Bar) test.uniqueMethod() 不起作用。谁知道额外的一组括号会有多大用处:)
【解决方案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

【讨论】:

    【解决方案3】:

    出现这个错误是因为编译器不知道testBar类型,它只知道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(); 
        }
    

    【讨论】:

      猜你喜欢
      • 2018-07-15
      • 2023-04-05
      • 2016-05-20
      • 2014-09-21
      • 2013-03-01
      • 2018-12-27
      • 2021-10-18
      • 2023-02-04
      相关资源
      最近更新 更多