1

我有一些这样的代码:

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

为什么会这样?

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

同样的概念适用于dynamic polymorphism

为什么会这样?

4

5 回答 5

9

由于 type of objis ExampleOne,编译器会搜索你objExampleOne类中调用的方法,如果找不到,就会抛出错误。

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

那是因为编译时检查是根据引用类型而不是实际对象类型来完成的。然后在运行时调用的实际方法取决于被引用的实际对象。这就是我们所说的方法调用的动态分派

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

abstract class ExampleOne{ 
    int dataOne=1000; 
    abstract void display(); 
    abstract void disp();
} 
于 2013-02-17T07:37:56.067 回答
4

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

于 2013-02-17T07:38:02.623 回答
1

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

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

于 2013-02-17T07:38:56.500 回答
1

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

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

ExampleTwo obj=new ExampleTwo(20); 
                  obj.disp(); 
                  obj.display();
于 2013-02-17T07:40:53.410 回答
1

好,

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

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

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

于 2013-02-17T07:43:27.500 回答