我有以下基类层次结构:
Index
(摘要)
RootIndex
AbstractSubIndex
(摘要)然后我还有两个班:
KPI
,应该继承AbstractSubIndex
,并添加自身独有的功能; SubIndex
,它应继承AbstractSubIndex
的功能以及RootIndex
中的功能。我会选择默认方法(Java 8),但我的代码不能用interface
s(实例变量)编写。更新
请注意Index
具有在其他类中继承的默认构造后功能;此构建后的功能必须执行一次。组合将至少强制它执行两次,这使得合成对我来说是一个不可行的解决方案。
结束更新
我无法找到任何非冗余的方法。
有什么想法吗?
答案 0 :(得分:1)
对我而言,这种解决方法基于组合 - 感谢@ kinga93和@AlexR的建议以及从头开始的面向方面的设计 - 但是在基类的原始代码中进行了更多的调整,这是我尽力避免的事情。
请注意,我已将@webuster的解决方案标记为已接受的解决方案,因为它更简单,并且可以完成工作。我发布这个是因为这是我最终选择的那个,因为从设计的角度来看,这对我来说更有意义,并且万一有人需要它。
Index
获取了不基于RootIndex
的代码,并将其打包在类ParentBehaviour
中,并在其位置添加了引用。AbstractSubIndex
中执行了相同的操作,获取了不基于Index
的代码,并将其包装在另一个类ChildBehavior
中,并在其位置添加了引用。SubIndex
中的作文,以及ParentBehavior
和ChildBehavior
的引用,同时继承自AbstractSubIndex
。KPI
中再次使用了作品,继承自AbstractSubIndex
,同时引用了ChildBehavior
。最终代码是这样的:
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
}
这样,SubIndex
和KPI
从Index
继承了AbstractSubIndex
的基本功能,从而继承了Index
所需的后构造功能重复,同时只从基类中获得所需的功能(通过ParentBehavior
和ChildBehavior
)。
答案 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();
}
}
除非有其他条件和约束,否则上述应该可以解决问题,我希望如此。您的代码可能与上面的格式不同,但您可以通过将其他代码提取到单独的方法中来将其添加到此表单中。