在Java中解决多重继承问题

时间:2014-08-07 13:05:42

标签: java inheritance multiple-inheritance

我有以下基类层次结构:

  • Index(摘要)
    • RootIndex
    • AbstractSubIndex(摘要)

然后我还有两个班:

  • KPI,应该继承AbstractSubIndex,并添加自身独有的功能;
  • SubIndex,它应继承AbstractSubIndex的功能以及RootIndex中的功能。我会选择默认方法(Java 8),但我的代码不能用interface s(实例变量)编写。

更新

请注意Index具有在其他类中继承的默认构造后功能;此构建后的功能必须执行一次。组合将至少强制它执行两次,这使得合成对我来说是一个不可行的解决方案。

结束更新

我无法找到任何非冗余的方法。

有什么想法吗?

4 个答案:

答案 0 :(得分:1)

对我而言,这种解决方法基于组合 - 感谢@ kinga93和@AlexR的建议以及从头开始的面向方面的设计 - 但是在基类的原始代码中进行了更多的调整,这是我尽力避免的事情。

请注意,我已将@webuster的解决方案标记为已接受的解决方案,因为它更简单,并且可以完成工作。我发布这个是因为这是我最终选择的那个,因为从设计的角度来看,这对我来说更有意义,并且万一有人需要它。

  1. 我从Index获取了不基于RootIndex的代码,并将其打包在类ParentBehaviour中,并在其位置添加了引用。
  2. 我在AbstractSubIndex中执行了相同的操作,获取了不基于Index的代码,并将其包装在另一个类ChildBehavior中,并在其位置添加了引用。
  3. 我使用了SubIndex中的作文,以及ParentBehaviorChildBehavior的引用,同时继承自AbstractSubIndex
  4. 我在KPI中再次使用了作品,继承自AbstractSubIndex,同时引用了ChildBehavior
  5. 最终代码是这样的:

    class ParentBehavior {
        // functionality that exists in RootIndex and SubIndex, which does not
        // depend on Index.
    }
    
    class ChildBehavior {
        // functionality that exists in SubIndex and KPI, which does not depend
        // on Index.
    }
    
    abstract class Index {
        // contains post-construction code.
        void foo();
    }
    
    class RootIndex extends Index {
        ParentBehavior parentBehavior;
    }
    
    abstract class AbstractSubIndex extends Index {
        // shared code between SubIndex and KPI
        ChildBehavior childBehavior;
    }
    
    class SubIndex extends AbstractSubIndex {
        ParentBehavior parentBehavior;
    }
    
    class KPI extends AbstractSubIndex {
        // unique functionality for KPI
    }
    

    这样,SubIndexKPIIndex继承了AbstractSubIndex的基本功能,从而继承了Index所需的后构造功能重复,同时只从基类中获得所需的功能(通过ParentBehaviorChildBehavior)。

答案 1 :(得分:0)

解决此类问题的标准方法是授权。

根据需要定义接口及其层次结构。定义具体的类。当属于不同继承分支的A类和B类应该共享功能时,在C类中实现它,并从A和B调用C的方法。

答案 2 :(得分:0)

使用合成而不是继承。在类中为AbstractIndex或RootIndex(甚至两个字段)声明一个字段。

答案 3 :(得分:0)

好的,所以根据我的理解,我认为以下内容可能会削减它。假设您的Index类为

的简化方案
abstract class Index {

    public Index() {
        // your code here
        // ...

        postConstruct();
    }

    void postConstruct() {
        // your post construction stuff
    }

    // assumed just one abstract method, may be a thousand like it
    abstract void foo(); 
}

和您的派生类型为

class RootIndex extends Index {
    // ...

    @Override
    void foo() {
        // your stuff
    }

    public void bar() {
        // your additional stuff
    }
}

abstract class AbstractIndex extends Index {
    // ...
}

我这样做会是这样的。创建一个公开RootIndex 附加功能签名的界面:

interface AdditionalFunctionalityInterface {
    void bar();
}

并让RootIndex实现它。然后,我将解决你曾经postConstruct的问题,如下所示:

class SubIndex extends AbstractIndex implements AdditionalFunctionalityInterface {

    private class AuxRootIndex extends RootIndex {
        @Override
        void postConstruct() {
            // DON'T do what super.postConstruct() does
            // might as well be empty if you wish
        }
    }

    // composition
    private AuxRootIndex myRootIndex;

    @Override
    void foo() {
        // your stuff

        // a little bit unclear here, you can keep the one from
        // AbstractIndex or the one from RootIndex if you want
        myRootIndex.foo();
    }


    @Override
    public void bar() {
        myRootIndex.bar();
    }
}

除非有其他条件和约束,否则上述应该可以解决问题,我希望如此。您的代码可能与上面的格式不同,但您可以通过将其他代码提取到单独的方法中来将其添加到此表单中。