Java中多重inheritance的替代方案

我创建了两个bean

class BackPageBean{ String backPage = null; : : : } class InformationMessageBean{ String informationMessage = null; : : : } 

现在,如果一个类是反向识别的,那么它将扩展backPageBean,或者如果它需要显示某种消息,那么它会扩展InformationMessageBean。

 class BackPageAware extends backPageBean{ } class InfoMessAware extends InformationMessageBean{ } someFunction () { if ( theObject instanceOf backPageBean ) { prepareTheBackPage ( theObject.getBackPage() ); } if ( theObject instanceOf InformationMessageBean ) { showtheInformation ( theObject.getMessage() ); } } 

现在问题是,如果我想要一个既是BackPageAware又是InformationAware的bean,因为我们没有多重inheritance,那么应该采用什么方法呢?

只是为了澄清我的评论。

就像Darth Eru说你创建了两个接口和两个默认实现。 如果您有一个需要这两个行为的bean,那么该类实现了两个接口,但您也创建了默认实现的变量。 这样你仍然不需要复制任何代码。

  interface InfoMessAware { String getMessage(); } interface BackPageAware { String getBackPage(); } class DefaultInfoMessAware { String getMessage() { return "message"; } } class DefaultBackPageAware { String getBackPage() { return "backPage"; } } class MyBean implements InfoMessAware, BackPageAware { private InfoMessAware messAware = new DefaultInfoMessAware(); private BackPageAware backPageAware = new DefaultBackPageAware(); String getMessage() { return messAware.getMessage(); } String getBackPage() { return backPageAware.getBackPage(); } } 

使用接口:

 interface InfoMessAware { String getMessage(); } interface BackPageAware { String getBackPage(); } class MyBean implements InfoMessAware, BackPageAware { String getMessage() { return "message"; } String getBackPage() { return "backPage"; } } 

然后用标准方法调用替换instanceof

您描述的问题需要使用组合,而不是inheritance。 该类是BackPageAware意味着它知道该类/function。 inheritance意味着它一个BackPage。 您已经描述了HAS A关系。

正如现在多次说过的那样,使用接口来定义用于检索对象具有的信息的合同。

您的两个原始类应该是Interfaces,每个类都有一个方法,它们检索实现应该返回的信息。

 public interface BackPageBean { public String getBackPage(); } public interface InformationMessageBean { public String getInformationMessage(); } 

如果您希望类实现BackPageBean和InformationMessageBean,您只需执行以下操作:

 public MyBean implements BackPageBean, InformationMessageBean { public String getBackPage() { return null; } public String getInformationMessage() { return null; } } 

一般来说,你应该尽可能避免扩展非抽象类,它会导致各种各样的问题。 相反,尝试使用组合而不是inheritance,其中涉及具体类,否则,尝试并坚持接口和偶尔的Abstract类。

正如在其他答案中所讨论的,可以使用接口和组合来模拟多inheritance,但代价是必须编写大量的样板代码。 然而,有许多项目可以在编译时(通过预处理器)或在运行时(例如jmixin )自动执行此操作 。

将BackPageAware和InformationAware声明为接口,创建实现这些接口的抽象类以提供默认function。 任何只需要两个接口之一的类都可以inheritance相应的抽象类。 需要两者的类都可以inheritance其中一个抽象类并实现其他接口,或实现两个接口,无论如何。 如果没有默认function,那么您甚至不需要抽象类。

您不能扩展多个类,但可以实现多个接口。 请记住,将接口应用于类时,类的对象与接口具有IS-A关系。

您可以将BackPageAwareInformationAware作为接口而不是类。 这使您可以在所引用的’bean’是BackPageAwareInformationAware的情况下从两个接口获取消息。

 public class Name implements BackPageAware, InformationAware {}