2

我知道Java禁止从多个类继承,并允许实现任意数量的接口。然而,尽管接口对多态性有好处,但它们不能包含任何他们的子类可能想要共享的实际代码。如果我有两个不同的超类共享我想在我的子类中使用的代码?继承两个Java类

示例:在我的程序中,有两个超类,一个与HashMaps一起工作,另一个与Strings一起工作,并且都有直接的子类,并且在那里都很好。但是现在我有三分之一需要两个超类的共同功能,但它只能扩展一个。有没有简单的方法来重新设计这个类结构,而不必重复大量的代码?

回答

6

我见过

  1. 同时从超
  2. 的提取接口创建一个实现接口的类完成这件事,然后将所有呼叫委派给实际对象

    public interface IFirst { public void foo(); } 
    
    public interface ISecond { public void bar(); } 
    
    public class Third implements IFirst, ISecond { 
        private IFirst first; 
        private ISecond second; 
    
        public Third(IFirst first, ISecond second) { 
         this.first = first; 
         this.second = second; 
        } 
    
        @Override 
        public void foo() { 
         first.foo(); 
        } 
        @Override 
        public String bar() { 
         return second.bar(); 
        } 
    } 
    

不会给你访问到受保护成员的类层次结构。如果这就是你正在寻找的东西,那么你在Java中运气不佳。但是,这将允许您使用多态性将此对象同时作为IFirst和ISecond来引用。因此,您可以在需要两种类型之一的外部代码中访问它。

注:我偷了JB的命名。

12

使用委托而不是继承:

public class Third implements FirstInterface, SecondInterface { 
    private First first; 
    private Second second; 

    public void foo() { 
     first.foo(); 
    } 

    public String bar() { 
     return second.bar(); 
    } 
} 
2

使用的组合物 - 基本上让你的新类扩展的类之一,在新的类,它是类的父类的成员变量2.或者你可以只是去整个猪,并在新类使用组成,并在其中有class1和class2类型的成员

1

我质疑任何设计,你有管理hashmaps类管理字符串之间有很多相互依赖性。但要直接回答你的问题,你可以让你的第三课包含Facade,它包装你的超类的实例,然后根据需要将它的方法委托给这些类。

1

解决此问题的一种方法是赞成合成而不是继承。如果您可以设计您目前想要扩展的两个类,以便它们可以用作新类的成员,那么您应该具有所需的灵活性。取而代之的

class MyClass extends MapBehavior, StringBehavior { ... } 

尝试

class MyClass { 
    MapBehavior mb; 
    StringBehavior sb; 
    ... 
} 
+1

与我的其他评论相同的问题 - 第二个代码块中的MyClass不是继承(或实现)任何东西 - 根本就没有继承。 –

+0

公平点。我会放弃编辑我的帖子,因为Ryan Gross已经发布了一个解决多态问题的类似片段。 – Eric

+0

(和其他人,显然) – Eric