Java:处理多个复杂接口而无需重复代码

Java:处理多个复杂接口而无需重复代码,java,inheritance,interface,multiple-inheritance,Java,Inheritance,Interface,Multiple Inheritance,我正在使用一个JavaAPI,它要求我实现许多相当大的接口。然而,通常只有一两个细节在不同的实现中有所不同,所以我制作了一些抽象基类来提供大部分实现 但是现在我遇到了需要从其他类扩展和/或实现多个这样的接口的情况,因此我无法扩展我的抽象基类 在C++中,我能够使用多重继承,也可以使用下面的其他技巧。然而,Java不允许以这种方式使用多重继承或泛型 class MyClass : public HelperForInterfaceA, public HelperForInterfaceB {...

我正在使用一个JavaAPI,它要求我实现许多相当大的接口。然而,通常只有一两个细节在不同的实现中有所不同,所以我制作了一些抽象基类来提供大部分实现

但是现在我遇到了需要从其他类扩展和/或实现多个这样的接口的情况,因此我无法扩展我的抽象基类

在C++中,我能够使用多重继承,也可以使用下面的其他技巧。然而,Java不允许以这种方式使用多重继承或泛型

class MyClass : public HelperForInterfaceA, public HelperForInterfaceB {...};
class template<class BASE> MyHelper : public BASE {...};
classmyclass:public-HelperForInterfaceA,public-HelperForInterfaceB{…};
类模板MyHelper:公共基{…};
我现在最好的想法是将抽象助手类的具体实现作为一个字段,然后将所有接口方法转发到该字段实例,如果需要,该字段将引用主对象以实现最后的细节

class MyClass extends A implements IB, IC {
    private static class B extends BAbstractHelper {
        private A a;
        public B(A a, int size) {
            super(size);
            this.a = a;
        }

        @Override
        public boolean foo(int x, int y) {
            return a.foo(x, y);
        }
    }
    private static class C extends CAbstractHelper {
        ...
    }


    private B b;
    private C c;
    private int range;

    @Override
    public boolean foo(int x, int y) {
        return x*x + y*y <= range*range;
    }

    @Override
    public float bar(float x, int y, String s) {
        return b.bar(x,y,s);
    }

    ...
}
class MyClass扩展了实现IB、IC的{
私有静态类B扩展了BAbstractHelper{
私人A;
公共B(A,整数大小){
超级(尺寸);
这个a=a;
}
@凌驾
公共布尔foo(整数x,整数y){
返回a.foo(x,y);
}
}
私有静态类C扩展了CAbstractHelper{
...
}
私人B,;
私人C C;
私有整数范围;
@凌驾
公共布尔foo(整数x,整数y){

return x*x+y*yJava的最佳实践是更喜欢组合而不是继承。使事情更简单,但创建更多的样板代码。创建委托方法的想法是正确的。一个好的Java IDE可以为您生成所有样板委托方法代码。JVM上的其他语言,如Scala(具有特性)让这更容易些。

这是一个很好的问题。我担心这会很痛苦:-(另一方面,我认为人们把构图看得太远了,认为这是对“重构图轻继承”的反应趋势。这可能是这家伙面对充满困难接口的代码的原因。如果你非常仔细地考虑你的类结构,那么继承通常是一个很好的解决方案。我很少需要使用组合,因为几乎所有东西都可以用继承很好地表示。听起来像异端,但创始人对继承如此兴奋是有原因的。它是一个非常有用的结构化工具。既然Java支持接口中的默认方法实现,那么通过多个接口就更容易做到这一点,而无需创建委托方法。