2

以下在 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 类)。
  • 这不是多重继承的钻石问题,因为对于使用谁的实现没有歧义。虽然有一种菱形图案 A->B,C->D 。
4

6 回答 6

4

除非您使用的是 Java 1.8,否则接口中不能有任何实现,所以您的问题是基于错误的假设:您只有A.fooinC和的实现D

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

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使用 a的默认实现并从viastatic void foo(B b)调用它。D.barHelperClass.foo(this)

于 2013-01-06T12:09:09.997 回答
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.*/};
}
于 2013-01-06T12:12:57.990 回答
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
}

不要犹豫,询问更多细节,我会酌情编辑。

于 2013-01-06T12:14:31.683 回答
0

您可能需要在这里重新设计,但是...

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

is valid only if interface B declares foo as a method signature (protected void foo();) and if D implements foo (since it would then implement the valid B interface). Thus bar() would then call the foo() method that D implements, since it would be most local to D.

于 2013-01-06T12:15:56.843 回答
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
} 
于 2013-01-06T12:10:09.640 回答
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 */
    }
  }
于 2013-01-06T12:20:50.443 回答