interface A { public void m1(); }
**//Gives error**
class D implements A { public void m1(int x) { } }
**//this doen't**
abstract class G implements A { public void m1(int x) { } }
我怀疑为什么抽象类能够覆盖而类D不能
如果我看到第二个案例
class X1
{
public void f2(){}
}
class X2 extends X1
{**//No error**
public void f2(int x){}
}
为什么public void m1()没有在D类中被覆盖,而相同类型的方法f2()在X2类中被覆盖 在这两种情况下,我们都是过度的,但为什么在接口案例类D不能和第二种情况下类X2可以覆盖。
答案 0 :(得分:3)
当有两个方法具有相同名称但参数类型(或计数)不同时,重载,而不是覆盖。
D
没有实现A
本身,因为它没有提供m1()
的实现 - 没有参数。它试图提供一个方法m1(int)
,但这无助于实现接口 - 所以它不会编译(因为它不是一个抽象类)。它当然可以提供两种方法。X1
提供方法f2()
,X2
扩展X1
并添加新的重载 f2(int)
- 但它没有不要覆盖X1
。特别是,如果你写:
X2 x2 = new X2();
x2.f2(10); // Calls X2.f2(int)
x2.f2(); // Calls X1.f2()
使用@Override
注释可以使所有这些更清晰:
class X1
{
public void f2(){}
}
class X2 extends X1
{
@Override public void f2(int x){}
}
现在出现错误:
error: method does not override or implement a method from a super type
@Override public void f2(int x){}
^
1 error
答案 1 :(得分:0)
您的课程D
和G
仍然是抽象的,因为您没有覆盖A.mi1()
。
D
收到错误,因为您尚未声明abstract
。将其设为abstract
或覆盖A.mi1()
。
在你的第二个片段中 - 你没有超越,而是超载。这两个是完全不同的功能。不要因为他们有相同的名字而被愚弄。函数名不是重载决策的唯一内容,参数也是如此。
答案 2 :(得分:0)
在D类中,你实际上并没有覆盖该方法。因为它是一个抽象方法,所以你应该在D类中实现该方法。然而,你正在做的是实现一个新的新方法'void m1(int x)',而不是实现'void m1()'。您正在重载该方法而不是实现/覆盖它。
使用抽象类时没有收到错误的原因是因为您没有义务从它继承的接口实现所有方法。但是,如果它们不是抽象的,你必须在G的子类中实现'void m1()'。
本质上:将接口A中的方法签名更改为:public void m1(int x);它会起作用。
答案 3 :(得分:0)
D和G都不会覆盖A.m1()
- 他们"重载"它。因此D缺少A.m1()
的实现。但是,G仍然是抽象的,因此不需要实现A.m1()
。
在X2的情况下,您再次重载(未覆盖)f2
。但这两者都是具体的方法,因此不会发生错误。