在Java中处理多重继承
我有以下基类层次结构:在Java中处理多重继承,java,inheritance,multiple-inheritance,Java,Inheritance,Multiple Inheritance,我有以下基类层次结构: 索引(摘要) RootIndex AbstractSubIndex(摘要) 然后我还有两门课: KPI,它应该继承AbstractSubIndex,并添加自身独有的功能 子索引,它应该继承抽象子索引的功能以及根索引中的功能。我会选择默认方法(Java8),但我有一些无法在interfaces(实例变量)中编写的代码 更新 请注意,Index具有默认的构造后功能,该功能在其他类中继承;此构建后功能必须执行一次。组合将迫使它至少执行两次,这使得组合对我来说是一个不
(摘要)索引
RootIndex
(摘要)AbstractSubIndex
,它应该继承KPI
,并添加自身独有的功能李>AbstractSubIndex
,它应该继承子索引
的功能以及抽象子索引
中的功能。我会选择默认方法(Java8),但我有一些无法在根索引
s(实例变量)中编写的代码interface
Index
具有默认的构造后功能,该功能在其他类中继承;此构建后功能必须执行一次。组合将迫使它至少执行两次,这使得组合对我来说是一个不可行的解决方案
结束更新
我找不到任何非冗余的方法来解决这个问题
有什么想法吗?解决这些问题的标准方法是授权
根据需要定义接口及其层次结构。定义具体的类。当属于不同继承分支的类A和类B共享功能时,应该在类C中实现它,并从A和B调用C的方法。使用组合而不是继承。在类中为AbstractIndex或RootIndex(甚至两个字段)声明一个字段。好的,据我所知,我认为以下内容可能会将其删除。假设您的
索引
类为
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
}
}
及
我会这样做。创建一个界面,公开RootIndex
附加功能的签名:
interface AdditionalFunctionalityInterface {
void bar();
}
并使RootIndex
实现它。然后,我将围绕你的一次施工后工作如下:
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();
}
}
我希望,除非有其他条件和限制,否则上述措施应该会奏效。您的代码可能与上面的格式不同,但您可以通过将其他代码提取到单独的方法中来实现此格式。对于我来说,奇怪的是,此解决方案基于组合-感谢@kinga93和@AlexR的建议以及从头开始的面向方面的设计-,但是对基类的原始代码进行了更多的调整,这是我尽力避免的 请注意,我已经将@webuster的解决方案标记为可接受的解决方案,因为它更简单,并且能够完成工作。我之所以发布这篇文章,是因为这是我最终选择的,因为从设计的角度来看,这对我来说更有意义,而且是为了防止有人需要它
RootIndex
中获取了不基于Index
的代码,并将其包装在类parentbehavior
中,并在其位置添加了一个引用AbstractSubIndex
中也做了同样的操作,将不基于Index
的代码包装到另一个类ChildBehavior
,并在其位置添加一个引用SubIndex
中使用了composition,引用了ParentBehavior
和ChildBehavior
,同时继承了AbstractSubIndex
KPI
中再次使用了composition,它继承了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
}
这样,
子索引
和KPI
从抽象子索引
继承索引
的基本功能,从而不重复地从索引
继承所需的后期构造功能,同时只从基类获得所需的功能(通过ParentBehavior
和ChildBehavior
).我知道子索引
应该从这两个类继承功能,并且它们可以很容易地通过一些嵌套类继承。子索引
应该从哪种类型派生?它既从抽象子索引
派生,也从根索引
派生。这两个类都具有构造子索引
中提供这两种功能,但我是从编译器的类型角度提出的。它仍然必须有一个类型。它不能同时充当类型a
和B
,除非它们中最多有一个是类,但您知道。抱歉,我误解了您的问题 :) . 从逻辑上讲,它是一个抽象子索引
。在问题中我忘了写一些东西,这使得这个解决方案对我来说不可行。索引中有默认的后期构造功能,它在RootIndex和AbstractSubIndex中都是继承的。在您提到的所有情况下,Composition将至少执行此功能两次。很抱歉,我之前没有提到这一部分;现在更新。谢谢你的回答,但我有点不清楚。我想你的意思是我用作文,这对我来说是行不通的。请检查问题中的更新部分。索引的默认后期构造逻辑必须在每个实例、每个子类或应用程序生命周期内运行一次?每个类/子类实例运行一次。这正是我要发布的内容。简单的构图不是答案,装饰师才是。你知道,我以前听说过装饰师,但从没想过这就是答案。我确实需要修改设计模式。谢谢你的提示。:)
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
}