让一个类成为几个超类的子类

时间:2015-10-19 13:56:41

标签: java inheritance

有几个(5+)类,在代码中我无法改变,我需要扩展几个字段。有没有办法在没有写入(并且每次需要更改某些内容时编辑)几乎完全相同的代码5次的情况下执行此操作?那么还有比这更优雅的方式:

class Subclass1 extends Superclass1 {
    private String newField;    

    public String getNewField() {
        return newField;
    }

    public void setNewField(String newField) {
        this.newField = newField;
    }

}
class Subclass2 extends Superclass2 {
    private String newField;    

    public String getNewField() {
        return newField;
    }

    public void setNewField(String newField) {
        this.newField = newField;
    }

}
//...

我不想要多重继承,我想要5个单独的子类 - 只是没有重复的代码,因为子类都添加完全相同。

我能想到的唯一选择是复制原始类并让副本扩展超类,这可能更糟糕。

3 个答案:

答案 0 :(得分:4)

不,你不能用Java做到这一点。您可以使用某些其他基于JVM的语言,例如Scala(traits)。但是,如果必须使用纯Java,则可以考虑以下内容:

  • 确定要添加的字段(希望是单一的)以及您想要的行为。
  • 创建一个包含所有字段和新方法的新类。例如:

    public class ExtraFields  // Don't use this name!
    {
        private String myExtraField1;
        private String myExtraField2;
        // etc.
    
        public void doSomethingWithExtraFields() {
            // etc.
        }
    }
    

然后,您可以采取以下方法之一:

  1. 对五个类中的每一个进行子类化,并添加一个字段,该字段是您在上面创建的类的实例,并相应地委托行为。如果必须在必须传入五个类之一的地方有额外的字段,则必须使用此方法。例如:

    public class Subclass1 extends Superclass1
    {
        private ExtraFields extraFields;
    
        public MySubclass()
        {
            super();
            extraFields = new ExtraFields();
        }
    
        public void doSomethingWithExtraFields()
        {
            extraFields.doSomethingWithExtraFields();
        }
    }
    
  2. 创建一个新的包装类,其中包含上面创建的新类的实例,以及这五个子类中的一个。您可以使用泛型使这种类型安全。例如:

    public class Wrapper<T>  // Don't use this name either...
    {
        private ExtraFields extraFields;
        private T myClass;
    
        public Wrapper(T myClass) {
            this.myClass = myClass;
            this.extraFields = new ExtraFields();
        }
    }
    

    在第二种方法中,您并不严格需要ExtraFields类。但是,为了封装相关的功能,这仍然是一个好主意。

  3. 希望有所帮助!

答案 1 :(得分:1)

由于您无法更改基类,因此无法消除冗余。 Eric Galluzzo想要将额外的字段存储在一个单独的类中是迄今为止最好的,但我不知道你的情况是否实用。如果不是,请创建一个定义额外字段的interface。您仍然需要进行大量的重复打字,但至少在您犯错误时,您会立即知道。

答案 2 :(得分:0)

您可以使用通用包装类,只要更改与其一起使用的其余代码不会太繁琐。

class Wrapper<E> {

    private E obj;
    private String newField;

    public Wrapper (E obj) {
        this.obj = obj;
    }
    public E get() {
        return obj;
    }

    public String getNewField() {
        return newField;
    }
    public void setNewField(String newField) {
        this.newField = newField;
    }
}