【问题标题】:assigning enum value programmatically in base class based on derived class基于派生类在基类中以编程方式分配枚举值
【发布时间】:2015-11-25 17:29:02
【问题描述】:

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

基类:

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

请帮忙。

【问题讨论】:

  • 这段代码看起来错误的原因有很多,包括受保护的枚举覆盖、代码重复和奇怪的类扩展。你为什么不使用接口呢?您使用 Enums 有什么原因吗?
  • 在 c++ 中,使用模板会很容易...所以,如果我理解正确,您希望 X、Y 和 Z 的值对于特定子类的每个实例都相同,但是不同的子类不同。好吧,枚举不是这项工作的正确工具。这听起来更像是你的类中需要静态字段
  • @GuillaumeF。这是现有代码,我想通过删除重复来优化它,但主要问题是枚举。另外,我需要整个枚举值 X 而不是单个数据。有什么办法可以优化吗?

标签: java enums


【解决方案1】:

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

如果您想继续使用枚举,可以考虑的解决方案是使用单个 MyEnum 枚举和 X, Y, Z,并在对象 BaseAB 中添加 showVal(MyEnum value) 方法. showVal 方法只会为所有枚举值(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 的状态。您将能够扩展该父对象并在子对象中提供您想要的任何整数值。

【讨论】:

  • 谢谢。因此,如果我必须四处优化这一点,我该如何解决这种情况?枚举在所有类中重复出现。有什么建议吗?
  • 您的所有类是否都需要将一对不同的整数关联到枚举的每个值?
  • 我编辑了我的问题以添加一个示例。 @rafael-naufal 的方法可能行得通,但这是我考虑的方法。
  • @user2281204,如果您认为此答案符合您的期望,请单击此答案旁边的复选标记图标。谢谢。
  • 它工作正常。谢谢。答案已被检查。
【解决方案2】:

我同意@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 的适当值。我还将Base 类的data 属性设置为受保护,并引用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接口,每个XYZ常量覆盖 getPair 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 2013-03-29
    • 2020-03-24
    • 2014-02-13
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多