覆盖案例:
class a{ public void m() {} }
class b extends a { @override public void m(){} }
隐藏案例:
class a { public static void m(){} }
class b extends a{ public static void m(){} }
这是一个隐藏另一个实例的方法吗?
interface i { void m(); }
interface j { void m(); }
class a implements i,j { void m(){} }
实例方法可以隐藏另一个实例方法吗?
答案 0 :(得分:3)
静态方法
在静态方法的情况下,您无论如何都必须为调用提供类(它们是类方法,而不是实例方法)因此&# 39; d不要隐藏,例如
A.m(); //call static method on class A (btw, Java convention is that class names start with a capital case letter)
B.m();
实例方法
实例方法无法隐藏其他方法,只需覆盖它们,例如如果B
延长A
,则只要您在m()
的实例上调用B
,B
版本m()
将被调用。
<强>接口强>
如果是接口,即使在多个接口中声明了,也要实现方法。
从Java 8开始,可能存在接口方法和IIRC的默认实现,具体实现将覆盖默认实现,而两个默认实现接口I
和J
将产生编译时错误(除非一个界面更具体,例如J
扩展I
。
答案 1 :(得分:2)
class a { public static void m(){} } class b { public static void m(){} }
这些类不共享共同的祖先,因此不能“隐藏”对方的方法。在Java中,子类中的同名实例方法总是覆盖超类的实例方法,没有其他语言中的隐藏机制(如Pascal,如果我没记错的话)。即使没有进行@Override
注释也是如此,注释只会使代码更具可读性并有助于防止拼写错误。
如果您更改了类b
以扩展类a
,那么它的静态方法m()
实际上会隐藏{{1}中的同名方法1}}。
这是the Oracle docs对此的评价:
隐藏静态方法和覆盖实例方法之间的区别具有重要意义:
- 被调用的重写实例方法的版本是子类中的版本。
- 被调用的隐藏静态方法的版本取决于它是从超类还是从子类调用。
对于你的界面:
a
接口本身不提供任何实例方法,它们只是实现类必须通过实现接口中声明的方法来遵守的契约。在您的情况下,您的接口只需要实现类(如类interface i { void m(); }
interface j { void m(); }
class a implements i,j { void m(){} }
)来实现方法a
。这就像你的妻子和女儿在星期六将他们带出冰淇淋一样承诺 - 对你女儿的承诺不会使你妻子的承诺无效,隐藏或否定。 ;)
简而言之:实例方法不能隐藏在Java中。
作为旁注:根据Java命名约定,类和接口应以大写字母开头。
答案 2 :(得分:0)
如果该方法匹配i和j中的两个签名(在这种情况下),则它们都实现它们。如果两个接口中的签名差异不足以使用重载,则它们不能合并为一个类。
在接口方面没有隐藏/覆盖,只有实现。
答案 3 :(得分:0)
对于接口i
和j
,如果一个类实现了两个接口,则没有违反接口。
对于静态方法,您无法隐藏它,因为您必须从类a.m()
和b.m()
调用它,因此它不会被隐藏。
最后,对于重写方法,超类的方法不被隐藏,它被覆盖。
答案 4 :(得分:0)
使用与超类方法相同的签名定义方法
在子类中,您可以overload the methods inherited from the superclass
。这样的overloaded methods neither hide nor override
超类实例方法 - they are new methods, unique to the subclass
。
答案 5 :(得分:0)
在@Override
的情况下,没关系。
界面情况不同:
一个接口定义一个契约,它只是说标记为接口的对象可以做某事。没有定义如何来做到这一点。因此,您不是隐藏方法,而是使用实现两个接口的类,您定义两个操作(具有相同名称)以相同的方式执行