以下是代码
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
原因:实际和正式的参数列表长度不同
为什么编译器在抱怨?方法重载/覆盖编译器的哪个规则正在应用?
您的回复将得到赞赏!!!
答案 0 :(得分:7)
hotel
的类型为Hotel
,没有 book(int)
方法。
如果您想致电book(int)
,则需要将hotel
的类型更改(或转换为)Test
Test hotel = new Test();
hotel.book(2); // No error
答案 1 :(得分:1)
因为编译器看到hotel
类型为Hotel
且Hotel
没有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) 两种情况下子类方法都可以工作,而在第二种情况下子类覆盖父类本方法