Java中多重继承的替代方案

时间:2009-06-24 13:26:10

标签: java multiple-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,那么因为我们没有多重继承,那么该方法应该是什么?

8 个答案:

答案 0 :(得分:11)

使用接口:

interface InfoMessAware {

     String getMessage();
}

interface BackPageAware {

     String getBackPage();
}

class MyBean implements InfoMessAware, BackPageAware {

     String getMessage() {
         return "message";
     }

     String getBackPage() {
         return "backPage";
     }
}

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

答案 1 :(得分:9)

只是为了澄清我的评论。

  

就像Darth Eru说你创造的那样   两个接口和两个默认值   实现。当你有一个豆子   这需要你的两种行为   有那个类实现这两个   接口,但你也创建   默认的变量   实现。这样你还是   不需要复制任何代码。

    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();
         }
    }

答案 2 :(得分:8)

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

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

答案 3 :(得分:1)

你的两个原始类应该是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;
  }
}

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

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

public class Name implements BackPageAware, InformationAware {}