Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can an Enum class extend another external library class?

Now I have an existing class that I would like to refactor to be an Enum. The class currently extends another class which is from external library. As I still would like to benefit from some logics from that extended class meanwhile would like to refactor. How should it be done?

In Java, an enum class cannot extend another class whereas it can implement interface. Or is it already wrong for the idea of refactoring it to be an Enum? Let me show it in the example code below.

Assume an existing class Existing is extending another class Parent and the Parent class is from an external library and it is NOT an interface.

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

The idea is to have those static final fields to be Enums, e.g.:

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

and possibly when needed, with new extra attr added as below:

enum NewDesign{
  A(attr1, attr2, newAttr),
  B(attr1, newAttr),
  C(attr1, attr2, newAttr),
  //...
  //constructor etc.
  //...
}
like image 877
qwop72 Avatar asked Jul 24 '19 07:07

qwop72


People also ask

Can an enum class extend another class?

Enum cannot extend any class in java,the reason is, by default Enum extends abstract base class java. lang. Enum. Since java does not support multiple inheritance for classes, Enum can not extend another class.

Can enum extend an interface?

Yes, Enum implements an interface in Java, it can be useful when we need to implement some business logic that is tightly coupled with a discriminatory property of a given object or class.

Can enum be used as base class for another class?

This is not possible. Enums cannot inherit from other enums.

Can enum extend a class C#?

The reason you can't extend Enums is because it would lead to problems with polymorphism.


2 Answers

If the main change that you need is to create an enum to get rid of static final fields, the easiest way to go about it is to create a different, enum type with initialized instances:

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

Depending on how you're using your Existing class currently, you may still be able to change it to an enum. In the following example, I expose an instance of Parent on the enum, assuming code using Existing can be changed to call 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);
        }
    }
}
like image 182
ernest_k Avatar answered Oct 22 '22 03:10

ernest_k


I think you can use composition:

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();
    }
}
like image 3
Shepherd Avatar answered Oct 22 '22 04:10

Shepherd