多重继承,组合功能



我有一个名为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);
    }
}

在本例中,DEaDEb是逻辑提供者,DE是状态提供者。现在,您可以向DE注入任何类型的逻辑实现者,并从中接收状态。

最新更新