Enum类如何扩展另一个外部库类?

时间:2019-07-24 07:13:05

标签: java inheritance enums interface

现在我有一个现有的类,我想将其重构为一个Enum。该类当前扩展了另一个类,该类来自外部库。我仍然想从扩展类的某些逻辑中受益,同时希望进行重构。应该怎么做?

在Java中,enum类不能扩展另一个类,而it can implement interface则不能扩展。或将其重构为枚举的想法已经是错误的吗?让我在下面的示例代码中展示它。

假定现有类已存在,则正在扩展另一个类Parent,并且Parent类来自外部库,它不是接口。

class Existing extends Parent{
    public static final Existing A = new Existing(...);
    ....
    public static final Existing Z = new Existing(...);

    public Existing(Srting attr1, String attr1){
        super(attr1, attr2);
    }

    public Existing(String attr1){
       super(attr1);
    }
}

这个想法是让那些静态的final字段成为Enums,例如:

enum NewDesign{
     A(attr1, attr2),
     B(attr1),
     C(attr1, attr2)
     //...;
     //constructor etc.
     //...
}

,并可能在需要时添加新的额外attr,如下所示:

enum NewDesign{
  A(attr1, attr2, newAttr),
  B(attr1, newAttr),
  C(attr1, attr2, newAttr),
  //...
  //constructor etc.
  //...
}

3 个答案:

答案 0 :(得分:5)

如果您需要进行的主要更改是创建一个枚举以摆脱静态的final字段,那么最简单的方法是使用初始化实例创建一个不同的枚举类型:

enum ExistingEnum {
    A("attr1", "attr2"), 
    Z("attr");

    private final Existing existing;

    ExistingEnum(String attr1) {
        this.existing = new Existing(attr1);
    }

    ExistingEnum(String attr1, String attr2) {
        this.existing = new Existing(attr1, attr2);
    }

    public Existing getExisting() {
        return existing;
    }
}

根据当前使用Existing类的方式,您仍然可以将其更改为枚举。在下面的示例中,假设可以将使用Parent的代码更改为调用Existing ...

,在枚举中公开Existing.A.getParent().parentMethod()的实例。
enum Existing {
    A("attr1", "attr2"),

    Z("attr");

    private final Parent existing;

    Existing(String attr1) {
        this.existing = new ParentImpl(attr1);
    }

    Existing(String attr1, String attr2) {
        this.existing = new ParentImpl(attr1, attr2);
    }

    public Parent getParent() {
        return existing;
    }

    // only needed if logic is overridden
    private static class ParentImpl extends Parent {
        public static final Existing A = "";
        public static final Existing Z = "";

        public ParentImpl(String attr1, String attr2) {
            super(attr1, attr2);
        }

        public ParentImpl(String attr1) {
            super(attr1);
        }
    }
}

答案 1 :(得分:3)

我认为您可以使用合成:

public class Parent {
    private String attr1;
    private String attr2;

    public Parent(String attr1, String attr2) {
        this.attr1 = attr1;
        this.attr2 = attr2;
    }

    public void doSomething() {
        // do something.
    }
}

// compose the class Parent
public enum NewDesign {
    A("attr1", "attr2"),
    B("attr1", "attr2")
    ;

    private Parent parent;

    NewDesign(String attr1, String attr2) {
        this.parent = new Parent(attr1, attr2);
    }
    public void func() {
        parent.doSomething();
    }
}

答案 2 :(得分:2)

  

由于我仍然想从扩展类的某些逻辑中受益,同时希望进行重构。

继承并不是您可以从库类中编写的逻辑中受益的唯一方法。合成(在Parent中有一个Existing作为字段)可能会起作用。

  

现在我有一个现有的类,我想将其重构为枚举。

为什么要枚举?您的Existing类具有两个构造函数,这意味着无论已定义的对象A ... Z为何,您都希望创建新实例。这不是枚举背后的想法。

  

并且可能在需要时添加了新的额外属性

当出现新属性时,重构所有常量可能很繁琐。添加新属性后,您将立即修改类。在我看来,这听起来并不合理,并且有点违反the open-closed principle-您实际上并没有开放使用枚举的扩展名。