为何编译器显示错误

时间:2013-12-09 09:54:52

标签: java polymorphism overloading method-overriding

以下是代码

class Hotel {
 public int bookings;
 public void book() {
    bookings++;
 }
}

public class Test extends Hotel{
 public void book() {
    bookings--;
 }

 public void book(int size) {
    book();
    super.book();
    bookings += size;
 }

 public static void main(String... args) {
   Hotel hotel = new Test();
   hotel.book(2);  // Compiler show error
    System.out.print(hotel.bookings);
 }        
}       
  类javaapplication1.Hotel中的 Erorr:方法手册无法应用于给定类型;

     

必需:没有参数

     

发现:int

     

原因:实际和正式的参数列表长度不同

为什么编译器在抱怨?方法重载/覆盖编译器的哪个规则正在应用?

您的回复将得到赞赏!!!

6 个答案:

答案 0 :(得分:7)

hotel的类型为Hotel没有 book(int)方法。

如果您想致电book(int),则需要将hotel的类型更改(或转换为)Test

   Test hotel = new Test();
   hotel.book(2);  // No error

答案 1 :(得分:1)

因为编译器看到hotel类型为HotelHotel没有book(int)函数:但是如果我们将其转换为Test并在其上调用book(int)

((Test)hotel).book(2);

我们不会有错误。可以从jls:15.12.2. Compile-Time Step 2: Determine Method Signature 部分解释该行为。

答案 2 :(得分:1)

您正在使用重载,这是一个编译时多态。所以当编译器看到     hotel.book(2); 它期望酒店的书籍方法版本(记住它的编译时间)。由于酒店版本的book方法不包含任何参数,因此它认为此调用无效,因此错误。

答案 3 :(得分:1)

您正在使Hotel的对象不是Test并调用函数book(int),这是Test中描述的方法。

Test的对象无法使用Hotel的方法。如果您使用:

Hotel hotel = new Hotel();
hotel.book();

那么没关系,因为使用book(int),您应该创建一个Test的对象。

Test hotel = new Test();
hotel.book(2);

由于Test有一个方法book(int),它不会覆盖超类方法。因此,您应该创建Test的对象才能访问book(int)

  

超类的对象只能调用子类重写的子类的方法。

答案 4 :(得分:1)

Hotal不知道方法public void book(int size),而对于调用,您使用的是Hotel的引用。

运行时多态性只不过是为所有实现基类/接口的人定义契约。这使得对象能够在不知道其确切类型的情况下彼此交互。在您的情况下,基类没有book(int)的合同, if(hotel instanceof Test){ ((Test)hotel).book(2); // Compiler show error } 是子类的自有属性。

作为快速修复,您可以尝试这样的事情,

  Test hotel = new Test();
   test.book(2);

Hotel

无论如何,您应该在{{1}}类

中声明/定义此方法

答案 5 :(得分:1)

这里我们实际上是使用父类酒店引用的子类对象。 但是书(int)只在子类中,所以我们不能使用父引用。 如果在酒店类中有方法书(int),则它是okey,子类方法将覆盖酒店类。

任一 1.Test t = new test(); t.book(2); 2.hotel类类有book(int)方法 酒店t =新测试(); t.book(2) 两种情况下子类方法都可以工作,而在第二种情况下子类覆盖父类本方法