Java中用于覆盖接口的替代方法是什么?

时间:2013-01-06 11:56:12

标签: java inheritance interface multiple-inheritance

以下在Java中是不可能的,因为接口没有实现:

class A {
    protected void foo() { /* A impl */ }
    protected void baz() { /* impl */ }
}
interface B {
    /* here's what's impossible to have in Java. */
    protected void foo() { /* B impl incl. call to baz() */ }
}

class C extends A {
    /* stuff that's not in B... */
}

class D extends C implements B {
    void bar() { foo(); /* uses the B impl */ }
}

class E extends A {
    void bar() { foo(); /* uses the A impl */ }
}

class F extends C implements B {
    void bar() { foo(); /* uses the B impl */ }
}

我想要的是D继承C,但不必覆盖foo()本身;相反,我希望它只是表示“我使用B的已知修改”。在这种情况下,什么是正确的习语?

注意:

  • 是的,我确实希望改变我的设计;但改变它是什么?这就是我来这里问的问题。
  • 我认识Java,请不要在答案中重新解释抽象类和接口。
  • 这应该可以通过多重继承实现--D可以继承C和B(假设没有其他冲突)。
  • 请Java 6; Java 7如果绝对必要; Java 8与我无关。
  • B实现不能移动到A中,因为A实现确实是默认的,其他类直接从它继承(例如E类)。
  • C和B彼此不熟悉,不能互相提及。
  • B实现不能向下移动到D,因为其他类需要它不熟悉D(例如F类)。
  • 这不是多重继承的diamond problem,因为没有关于使用其实现的含糊之处。尽管存在一种菱形图案A-> B,C-> D。

6 个答案:

答案 0 :(得分:4)

除非您使用的是Java 1.8,否则您无法在界面中进行任何实现,因此您的问题基于错误的假设:您只能在A.foo和{{C中执行D 1}}。

使用Java 1.8,您可以在接口中使用所谓的虚拟扩展方法。应该可以使用following syntax

class ExtenderOfB {
  public static void foo(B b) {
    //...
  }
}

interface B {
  public void foo() default ExtenderOfB.foo;
}

class D extends C implements B {
  public void bar() {
    B.super.foo();
  }
}

然而,由于魔法本质上归结为调用静态方法,你可以为自己做到这一点:

创建一个助手类,使用B.foo提供static void foo(B b)的默认实现,并通过D.barHelperClass.foo(this)调用。

答案 1 :(得分:0)

您可以使用multilevel inheritance

解决此问题
class A
{
    //implementation of A
}

class B extends A
{
  public void foo()
 {
  //you can give your implementation of foo() here
 }
  //includes A's methods also.

}

class C extends B
{
  //will have methods from both A and B
} 

答案 2 :(得分:0)

这是你要找的吗? (这应该在评论中,因为我不确定你在寻找什么,但它并没有很好地显示在那里。)

interface A {
    void foo();
    void baz();
}
class B extends A{
    void foo(){/* B's impl. (must be impl.)*/};
    void baz(){/* B's impl. (must be impl.)*/};
}

class C extends A {
    void foo(){/* C's impl. (must be impl.)*/};
    void baz(){/* C's impl. (must be impl.)*/};
}

class D extends C {
    void foo(){/* D's impl */};
    void baz(){/* D's impl, if not included C's impl will be used */};
}

class E extends B {
    void foo(){/* E's impl, if not included B's impl will be used.*/};
    void baz(){/* E's impl, if not included B's impl will be used.*/};
}

或者,如果你希望B和C都从A共享方法,你会这样做......

class A {
    void foo(){ /*(must be impl.)*/ };
    void baz(){ /*(must be impl.)*/ };
}

class B extends A {
    void foo(){/* B's impl, if not included A's impl will be used*/};
    void baz(){/* B's impl, if not included A's impl will be used*/};
}

class C extends A {
    void foo(){/* C's impl, if not included A's impl will be used*/};
    void baz(){/* C's impl, if not included A's impl will be used*/};
}

class D extends C {
    void foo(){/* D's impl, if not included C's impl will be used */};
    void baz(){/* D's impl, if not included C's impl will be used */};
}

class E extends B {
    void foo(){/* E's impl, if not included B's impl will be used.*/};
    void baz(){/* E's impl, if not included B's impl will be used.*/};
}

如果你想让A实现foo(),而不是baz(),那么你就会把它变成抽象的,就像这样......

abstract class A {
    void foo(){ /*(must be impl.)*/ };
    abstract void baz();
}
class B extends A{
    void foo(){/* B's impl, if not included A's impl will be used*/};
    void baz(){ /*(must be impl.)*/ };
}

class C extends A {
    void foo(){/* C's impl, if not included A's impl will be used*/};
    void baz(){ /*(must be impl.)*/ };
}

class D extends C {
    void foo(){/* D's impl, if not included C's impl will be used */};
    void baz(){/* D's impl, if not included C's impl will be used */};
}

class E extends B {
    void foo(){/* E's impl, if not included B's impl will be used.*/};
    void baz(){/* E's impl, if not included B's impl will be used.*/};
}

答案 3 :(得分:0)

这里有关于接口和抽象类的小故障课程......

Java确实没有多重继承,因为你只能扩展一个类 - 但是,你可以实现多个接口。

还有抽象类。说你有:

interface B {
    void foo();
}

// A is abstract, and it does not implement foo(): this will be left to 
// its inheritors
abstract class A implements B {
    // Method with implementation
    protected void bar() {}
    // Method which must be implemented in inheriting classes
    abstract void baz();
}

// Concrete implementation of A: note that there is no need to specify
// "implements B" since A already does
class C extends A {
    // C must implement baz()  since it is declared abstract in A,
    // but must also implement foo() since A implements B, and A
    // has no implementation of it
}

此外,抽象类可以扩展另一个抽象类:

// D also implements B since A does.
abstract class D extends A {
    // But this time, D implements foo() from B
    @Override
    void foo() {}
}

class E extends D {
    // E must still implement the abstract baz() method declared in A
}

请不要犹豫,要求提供更多细节,我会酌情进行编辑。

答案 4 :(得分:0)

你可能需要在这里进行重新设计,但是......

class D extends C implements B {
    void bar() {
        foo(); /* used the B impl */
}
仅当interface Bfoo声明为方法签名(protected void foo();)且D实现foo时,

才有效(因为它会实现有效B接口)。因此,bar()会调用foo()实现的D方法,因为它对D来说是最本地的。

答案 5 :(得分:0)

在场景中,一个类A应该实现接口B,并且两个都有方法foo()

然后C类扩展A它不必实现B,因为它具有超类的默认实现。

然后D类扩展C并用方法foo()包装方法bar()而不覆盖它。这是成语。

代码

  interface B {
    void foo();
  }

  class A  implements B {
    public void foo() {
      /* B impl */
    }
  }

  class C extends A  {
    /* stuff that's not in B... */
  }

  class D extends C  {
    void bar() {
      foo(); /* used the B impl */
    }
  }