【发布时间】:2015-07-24 18:23:09
【问题描述】:
我试图了解 Java 如何处理当具体类从不同类/接口继承(抽象或具体)具有相同名称的方法时出现的歧义情况。
我无法找到一般规则,这就是为什么我决定一劳永逸地使用实用的方法来花一些时间来解决这个问题。
我考虑了 8 种不同的情况,结合
- 抽象方法
- 非抽象方法
- 抽象类
- 接口
导致这个方案:
+-------------------------+
| INTERFACE |
+----------+--------------|
| abstract | non-abstract |
| method | method |
+-----------+--------------+----------+--------------+
| | abstract | | |
| ABSTRACT | method | 1a | 2a |
| +--------------+----------+--------------+
| CLASS | non-abstract | | |
| | method | 3a | 4a |
+-----------+--------------+----------+--------------+
| | abstract | | |
| | method | 1b | 2b |
| INTERFACE +--------------+----------+--------------+
| | non-abstract | | |
| | method | 3b | 4b |
+-----------+--------------+----------+--------------+
这里每个案例都被实施和评论:
// (1a)
// A - abstract method
// I - abstract method
//
// Implementation needed to avoid compilation error:
// "The type B1 must implement the inherited abstract method A1.foo()"
//
abstract class A1{ abstract void foo(); }
interface I1{ void foo(); }
class B1 extends A1 implements I1{ public void foo(){} }
// (2a)
// A - abstract method
// I - non-abstract method
//
// Implementation needed to avoid compilation error:
// "The type B2 must implement the inherited abstract method A2.foo()"
//
abstract class A2{ abstract void foo(); }
interface I2{ default void foo(){} }
class B2 extends A2 implements I2{ public void foo(){} }
// (3a)
// A - non-abstract method
// I - abstract method
//
// Implementation not needed
//
abstract class A3{ public void foo(){} }
interface I3{ void foo(); }
class B3 extends A3 implements I3{ }
// (4a)
// A - non-abstract method
// I - non-abstract method
//
// Implementation not needed
//
abstract class A4 { public void foo(){System.out.println("A4");}}
interface I4{default void foo(){ System.out.println("I4");} }
class B4 extends A4 implements I4{ B4(){foo();} /*prints "A4"*/ }
// (1b)
// J - abstract method
// K - abstract method
//
// Implementation needed to avoid compilation error:
// "The type C1 must implement the inherited abstract method K1.foo()"
//
interface J1{ void foo(); }
interface K1{ void foo(); }
class C1 implements J1,K1{ public void foo(){} }
// (2b)
// J - abstract method
// K - non-abstract method
//
// Implementation needed to avoid compilation error:
// "The default method foo() inherited from K2 conflicts with another
// method inherited from J2"
//
interface J2{ void foo(); }
interface K2{ default void foo(){} }
class C2 implements J2,K2{ public void foo(){} }
// (3b)
// J - non-abstract method
// K - abstract method
//
// Implementation needed to avoid compilation error:
// "The default method foo() inherited from J3 conflicts with another
// method inherited from K3"
//
interface J3{ default void foo(){} }
interface K3{ void foo(); }
class C3 implements J3,K3{ public void foo(){} }
// (4b)
// J - non-abstract method
// K - non-abstract method
//
// Implementation needed to avoid compilation error:
// "Duplicate default methods named foo with the parameters () and ()
// are inherited from the types K4 and J4"
//
interface J4{ default void foo(){} }
interface K4{ default void foo(){} }
class C4 implements J4,K4{ public void foo(){} }
无论如何,尽管我能够理解示例中的大多数情况,但我仍然无法推断出任何“一般规则”。
例如,我不明白为什么情况 2a 和 3a 工作方式不同,即为什么抽象类给出的实现被接受,而抽象类给出的实现界面没有。
我的最后一个问题是:真的存在任何“一般规则”吗?有什么方法可以预测编译器的行为而不必记住每个案例?
编辑
这可能是微不足道的,但我认为它可能对其他人放下我的考虑有用。
我认为您可以将所有问题总结为这个简单的步骤:
给出这样的示例代码
abstract class A{abstract void foo();}
abstract class B extends A {protected void foo(){}}
interface I{void foo();}
interface J{default void foo(){}}
class C extends B implements I,J{}
-
考虑你的类 C 由它的所有方法和继承的方法组成(称之为 C*)
class C* implements I,J{protected void foo(){};} -
根据 C* 实现的接口验证 C*(来自接口的每个方法歧义,包括默认方法,都必须在 C 中通过提供实现来解决)。
3a。如果 C* 给出了一个有效的实现,则在此处停止
(it's not the case because method visibility cannot be reduced from public to protected)3b。否则在 C 中需要一个有效的实现
class C extends B implements I,J{public void foo(){}}
【问题讨论】:
-
请格式化您的帖子。我在使用您提供的基于文本的图表时遇到问题
-
我可以看到所有的格式都正确,你指的是什么?
-
@VinceEmigh 如果您使用的是移动设备,他们有时会为代码块使用可变宽度字体。
-
我在打电话。文本没有对齐,我真的无法匹配任何东西;该图表的格式不适合移动设备。以后,我会尝试使用图片来确保每个人看到的结果都一样
-
在我的安卓手机上,使用 SO 应用,一切正常,对不起!
标签: java oop interface overriding abstract