基于派生类以编程方式在基类中分配枚举值

时间:2015-11-25 17:29:03

标签: java enums

我有一个带有两个派生类的基类,它们似乎都使用相同的枚举。 我想在基类中使用枚举,但根据使用的派生类的实例更改指定的值。 我该怎么做?

基类:

public class Base {
    private MyEnum data = MyEnum.Z;
    public Base() {

    }
    public void baseMethod() {
        System.out.println("base data:? "+MyEnum.X);
        data = MyEnum.Y;
        data.showVal();
        System.out.println("base value:? "+data);
    }
    //enum yet to be added
        protected enum MyEnum {
            X(0,2),
            Y(1,3),
            Z(4,5);
            private int a,b;
            MyEnum(int x, int y) {
                a=x;
                b=y;
            }
            public void showVal() {
                System.out.println("a="+a+",b="+b);
            }
        }
}

两个派生类:

public class A extends Base {
    private MyEnum data = MyEnum.Z;
    public A () {

    }
    public void firstMethod() {
        System.out.println("A's DATA: "+MyEnum.X);
        data = MyEnum.Y;
        data.showVal();
        System.out.println("A's value: "+data);
        baseMethod();
    }
        protected enum MyEnum {
           //values are different
            X(10,11),
            Y(12,13),
            Z(14,15);
            private int a,b;
            MyEnum(int x, int y) {
                a=x;
                b=y;
            }
            public void showVal() {
                System.out.println("a="+a+",b="+b);
            }
        }
}

public class B extends Base {
    private MyEnum data = MyEnum.Z;
    public B() {

    }
    public void secondMethod() {
        System.out.println("B'S DATA: "+MyEnum.X);
        data = MyEnum.Y;
        data.showVal();
        System.out.println("B's value: "+data);
        baseMethod();
    }
        protected enum MyEnum {
            //values are different
            X(20,21),
            Y(22,23),
            Z(24,25);
            private int a,b;
            MyEnum(int x, int y) {
                a=x;
                b=y;
            }
            public void showVal() {
                System.out.println("a="+a+",b="+b);
            }
        }
}

请帮忙。

2 个答案:

答案 0 :(得分:1)

Enums are basically final classes that you can't extend。你可以在枚举中实现一个接口,但你不能扩展枚举来改变它的一个方法或枚举的具体值(你所指的整数对)。

如果您想继续使用枚举,要考虑的解决方案是在MyEnum中添加一个X, Y, Z枚举,并在对象showVal(MyEnum value)中添加Base方法,ABshowVal方法只会为您的所有枚举值(XYZ)关联正确的整数对。

以下是此方法的逻辑:

MyEnum.java

public enum MyEnum{
    X,Y,Z
}

Main.java

public class Main{

     public static void main(String []args){
        MyEnum value = MyEnum.X;

        System.out.println("With Base:");
        Base base = new Base();
        System.out.println(base.showVal(value));//prints "a=0,b=2"

        System.out.println("With A:");
        A a = new A();
        System.out.println(a.showVal(value));   //prints "a=10,b=11"

        System.out.println("With B:");
        B b = new B();
        System.out.println(b.showVal(value));   //prints "a=20,b=21"

     }
}

Base.java

public class Base{

    public Base(){
        //Do something...
    }

    public String showVal(MyEnum value){
        switch(value){
            case MyEnum.X:
                return "a=0,b=2";
            case MyEnum.Y:
                return "a=1,b=3";
            case MyEnum.Z:
                return "a=4,b=5";
        }

    }
}

A.java

public class A extends Base{

    public A(){
        //Do something...
    }

    @Override
    public String showVal(MyEnum value){
        switch(value){
            case MyEnum.X:
                return "a=10,b=11";
            case MyEnum.Y:
                return "a=12,b=13";
            case MyEnum.Z:
                return "a=14,b=15";
        }

    }
}

B.java

public class B extends Base{

    public B(){
        //Do something...
    }

    @Override
    public String showVal(MyEnum value){
        switch(value){
            case MyEnum.X:
                return "a=20,b=21";
            case MyEnum.Y:
                return "a=22,b=23";
            case MyEnum.Z:
                return "a=24,b=25";
        }

    }
}

如果您不介意更改结构,请使用对象存储代表XYZ的状态。您将能够扩展该父对象,并在子对象中提供所需的整数。

答案 1 :(得分:0)

我同意@cydrickt,下面有一个可能的解决方案,更改MyEnum的结构。

我创建了一个名为IMyEnum的简单接口,它有一个创建Pair值的方法:

public interface IMyEnum {
    void showVal();

    Pair getPair();
}

public class Pair {

    private final int a;

    private final int b;

    public Pair(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }
}

所有MyEnum类都实现了IMyEnum接口,每个枚举常量都覆盖getPair方法,返回ab的相应值。我还使data类的Base属性受到保护,并引用IMyEnum类型。以下是重构后Base类的示例:

public class Base {

protected IMyEnum data = MyEnum.Z;

public Base() {

}

public void baseMethod() {
    System.out.println("base data:? " + MyEnum.X);
    data = MyEnum.Y;
    data.showVal();
    System.out.println("base value:? " + data);
}

// enum yet to be added
protected enum MyEnum implements IMyEnum {
    X(0, 2) {
        @Override
        public Pair getPair() {
            return new Pair(X.a, X.b);
        }
    },
    Y(1, 3) {
        @Override
        public Pair getPair() {
            return new Pair(Y.a, Y.b);
        }
    },
    Z(4, 5) {
        @Override
        public Pair getPair() {
            return new Pair(Z.a, Z.b);
        }
    };
    private int a, b;

    MyEnum(int x, int y) {
        a = x;
        b = y;
    }

    @Override
    public void showVal() {
        System.out.println("a=" + a + ",b=" + b);
    }
 }
}

其他两个类AB类似于Base类,其MyEnum类必须实现IMyEnum接口,每个XY 1}},ZgetPair常量覆盖 :remote => true方法。