【问题标题】:Why won't Java compile this code?为什么Java不编译这段代码?
【发布时间】:2013-02-17 07:36:33
【问题描述】:

我有一些这样的代码:

abstract class ExampleOne {
   int dataOne = 1000;

   abstract void display();
}

class ExampleTwo extends ExampleOne {
   int dataTwo;

   ExampleTwo(int varOne) {
      dataTwo = varOne;
   }

   public void disp() {
      System.out.println("Testing");
   }

   public void display() {
      System.out.println(dataOne);
   }
}

class Example {
   public static void main(String args[]) {
      ExampleOne obj = new ExampleTwo(20);
      obj.disp();
      obj.display();
   }
}

当我编译这个时,我得到一个错误:

                obj.disp(); 
                     ^
  symbol:   method disp()
  location: variable obj of type ExampleOne

为什么会这样?

我将ExampleTwo的实例分配给ExampleOne,为什么Java不选择ExampleOne实例而不是ExampleTwo

同样的概念适用于dynamic polymorphism

为什么会这样?

【问题讨论】:

    标签: java class abstract-class abstract


    【解决方案1】:

    由于obj的类型是ExampleOne,编译器会在ExampleOne类中搜索你在obj上调用的方法,如果找不到,就会抛出错误。

    为什么 Java 不选择 ExampleOne 实例而不是 ExampleTwo?

    这是因为编译时检查是基于引用类型而不是实际对象类型。然后在运行时调用的实际方法是根据被引用的实际对象来决定的。这就是我们所说的方法调用的Dynamic Dispatch

    您可以将抽象的 disp() 方法添加到您的 ExampleOne 类中,以确保编译器对调用感到满意。

    abstract class ExampleOne{ 
        int dataOne=1000; 
        abstract void display(); 
        abstract void disp();
    } 
    

    【讨论】:

      【解决方案2】:

      您的方法仅在ExampleTwo 中定义,而不在ExampleOne 中定义。这会导致编译错误。

      【讨论】:

      • 不正确..在运行时应该是ExampleTwo..错误是因为编译器无法在编译时找到方法
      【解决方案3】:

      您的对象类型是ExampleOne。即使您创建了ExampleTwo 的实例,编译器已知的对象类型(即方法和成员)也是ExampleOne,它没有声明 disp()。

      如果你希望它以多态方式使用,你应该在ExampleOne 中声明一个抽象方法disp()

      【讨论】:

        【解决方案4】:

        基类对象只能访问它自己的类Methods。但disp() 不是它的方法。所以这就是你得到错误的原因。

        为了避免错误,你可以这样做:

        ExampleTwo obj=new ExampleTwo(20); 
                          obj.disp(); 
                          obj.display();
        

        【讨论】:

          【解决方案5】:

          嗯,

          背后的概念是,通过这个 java 结构,您将使用 ExampleTwo 的版本调用 ExampleOne 的方法。

          意味着,您只能调用引用变量类型的方法(在您的情况下是 ExampleOne )。但是调用的方法版本将是底层对象类型(即 ExampleTwo)。并且通过多态性促进了它。

          这里值得一提的是,您可以将对象分配给其类型的任何引用变量或其任何超类,在层次结构中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-14
            • 2012-07-06
            • 2013-08-08
            • 2010-10-24
            • 1970-01-01
            • 1970-01-01
            • 2013-03-26
            相关资源
            最近更新 更多