繁体   English   中英

Java中通过接口覆盖的替代方法是什么?

[英]What's the alternative in Java for overriding through an interface?

在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。

除非您使用Java 1.8,否则接口中将没有任何实现,因此您的问题基于错误的假设:您只能在CD实现A.foo的实现。

使用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();
  }
}

但是,由于魔术本质上可以归结为调用静态方法,因此您可以自己完成此操作:

创建一个使用static void foo(B b)提供B.foo默认实现的帮助程序类,并通过D.bar HelperClass.foo(this)D.bar调用它。

您可以使用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
} 

这是您要找的东西吗? (这应该在注释中,因为我不确定您要查找的内容,但是它并不能很好地显示在其中。)

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.*/};
}

关于接口和抽象类的一些速成课程...

从您只能扩展一个类的角度来看,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
}

请随时询问更多详细信息,我将酌情进行编辑。

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

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

仅在interface B foo声明为方法签名( protected void foo(); )并且D实现foo (因为它将随后实现有效的B接口)时才有效。 因此, bar()然后将调用D实现的foo()方法,因为它对于D来说是最本地的。

在这种情况下,一个类A应该实现接口B,并且两者都具有方法foo()

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

然后,类D扩展了C,并用方法bar()包装了方法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 */
    }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM