我有一个名为DE
的基本算法类。它有a()
、b()
两种实现方式。我想测试这个算法的一个变体,命名为DEa
。所以,我在做DEa extends DE
,我重写方法a()
。还有另一种变体,算法DEb
。我正在做同样的事情,DEb extends DE
和重写b()
。现在,我想测试算法DEab
。问题来了。如果我写DEab extends DEa
,它已经覆盖了a()
方法,但不是b()
,我将不得不从DEb
复制b()
,这是丑陋的,更难维护。
代码示例:
class DE { int i; void a() { i = 1; } void b() { i++; } };
class DEa extends DE { void a() { i = 2; } };
class DEb extends DE { void b() { i--; } };
// class DEab extends DEa, DEb - can't write like this
class DEab extends DEa { void b() { i-- }; } // but this is copy-paste :c
我尝试了interface A
, interface B
和后来的DE implements A, B
, DEa extends DE
, DEb extends DE
…基本上是同样的问题:
interface A { void a(); } // methods in interfaces must be abstract
interface B { void b(); }
class DE implements A, B { int i; void a() { i = 1; } void b() { i++; } };
class DEa extends DE { void a() { i = 2; } };
class DEb extends DE { void b() { i--; } };
class DEab extends // ... well it give me nothing
如何做到没有复制粘贴?
你可以使用这个模式。
public interface A {
public void a();
}
public interface B {
public void b();
}
public class ABComposition implements A, B {
private A a;
private B b;
public ABComposition(A a, B b) {
this.a = a;
this.b = b;
}
@Override
public void a() {
a.a();
}
@Override
public void b() {
b.b();
}
}
Java中没有多重继承。您只能实现多个接口(您提供实现),但只能有一个(直接)超类。
无论如何你都可以使用合成,通过创建
public class DEab extends DE {
private DEa dea = new DEa();
private DEb deb = new DEb();
public int a() {
return dea.a();
}
public int b() {
return deb.b();
}
}
如果你的类逻辑支持它。
更新:在更新问题之后,我坚持使用更简单的"不,Java不支持多重继承"
在你对共享状态假设的评论之后,我可以建议你重构@Toilal方法的版本:
interface A {
public int a();
}
interface B {
public int b(int i);
}
class DEa implements A {
@Override
public int a() {
return 1;
}
}
class DEb implements B {
@Override
public int b(int i) {
return i + 1;
}
}
class DE {
private int i;
private A a;
private B b;
public DE(A a, B b) {
this.a = a;
this.b = b;
}
public int getI() {
return i;
}
public void a() {
i = a.a();
}
public void b() {
i = b.b(i);
}
}
在本例中,DEa
和DEb
是逻辑提供者,DE
是状态提供者。现在,您可以向DE
注入任何类型的逻辑实现者,并从中接收状态。