Enum将工厂称为Java内部Enum

时间:2017-03-23 14:10:16

标签: java enums factory

我尝试将Enum样式的工厂模式实现为内部枚举, 但它不起作用。 有没有将内部枚举分离成新文件的解决方案? 换句话说,内部Enum风格的工厂模式是否可能?

代码如下。

public class SampleParent {

    private class InnerChild { }
    private class InnerChildA extends InnerChild { }
    private class InnerChildB extends InnerChild { }
    private class InnerChildC extends InnerChild { }

    enum InnerChildEnum {
        CHILD_A {
            @Override
                public InnerChild getInstance() {
                    return new InnerChildA();  // compile error
                }
        },
        CHILD_B {
            @Override
                public InnerChild getInstance() {
                    return new SampleParent.InnerChildB();  // compile error
                }
        },
        CHILD_C {
            @Override
                public InnerChild getInstance() {
                    return SampleParent.new InnerChildC();  // compile error
                }
        },
        ;

        public abstract InnerChild getInstance();
    }

    private static class InnerChildFactoryEnumStyled {
        public static InnerChild getInnerChild(InnerChildEnum child) {
            return child.getInstance();
        }
    }


    public static void main(String[] args) {

        // I want to write this way
        InnerChild child = InnerChildFactoryEnumStyled.getInnerChild(InnerChildEnum.CHILD_A);
    }
}

编译错误消息在

下面
$ javac SampleParent.java 
SampleParent.java:12: error: non-static variable this cannot be referenced from a static context
                return new InnerChildA();
                       ^
SampleParent.java:18: error: non-static variable this cannot be referenced from a static context
                return new SampleParent.InnerChildB();
                       ^
SampleParent.java:24: error: cannot find symbol
                return SampleParent.new InnerChildC();
                       ^
  symbol: variable SampleParent
3 errors

3 个答案:

答案 0 :(得分:5)

您的内部类不是静态的,因此它们必须引用封闭类SampleParent的实例。将您的班级声明更改为

private static class InnerChild { }
private static class InnerChildA extends InnerChild { }
private static class InnerChildB extends InnerChild { }
private static class InnerChildC extends InnerChild { }

你可以。 G。你的枚举中return new InnerChildA();

答案 1 :(得分:2)

要实例化一个无静态内部类(UITableViewdf['third'] = pd.DataFrame(np.random.random((4,1))) 等...),您需要使用封闭类型的实例(InnerChildA)限定实例化。 你必须这样做:InnerChildB

在您的情况下,您可以在SampleParent枚举中声明并实例化静态new ExternalClass().new InternalClass()实例,并在枚举值声明的每个实现的SampleParent方法中重复使用它。

InnerChildEnum

答案 2 :(得分:0)

改进代码在这里,以防万一。

public class SampleParent {

    private String foo = "foo";

    private abstract class InnerChild {
        public abstract void doSomething();
    }
    private class InnerChildA extends InnerChild {
        public void doSomething() {
            System.out.println(foo);  // refer sampleParent.foo, not original's foo
        }
    }
    private class InnerChildB extends InnerChild {
        public void doSomething() {
            System.out.println(foo);  // refer sampleParent.foo, not original's foo
        }
    }
    private class InnerChildC extends InnerChild {
        public void doSomething() {
            System.out.println(outer().foo);  // refer sampleParent.foo, not original's foo
        }
    }

    enum InnerChildEnum {
        CHILD_A {
            @Override
            public InnerChild getInstance() {
                return sampleParent.new InnerChildA();
            }
        },
        CHILD_B {
            @Override
            public InnerChild getInstance() {
                return sampleParent.new InnerChildB();
            }
        },
        CHILD_C {
            @Override
            public InnerChild getInstance() {
                return sampleParent.new InnerChildC();
            }
        },
        ;

        private static SampleParent sampleParent = new SampleParent();
        public abstract InnerChild getInstance();
    }

    private static class InnerChildFactoryEnumStyled {
        public static InnerChild getInnerChild(InnerChildEnum child) {
            return child.getInstance();
        }
    }


    public static void main(String[] args) {
        System.out.println("Hello World.");

        // I want to write this way
        InnerChild childA = InnerChildFactoryEnumStyled.getInnerChild(InnerChildEnum.CHILD_A);
        childA.doSomething();

        InnerChild childB = InnerChildFactoryEnumStyled.getInnerChild(InnerChildEnum.CHILD_B);
        childB.doSomething();

        InnerChild childC = InnerChildFactoryEnumStyled.getInnerChild(InnerChildEnum.CHILD_C);
        childC.doSomething();
    }

    public SampleParent outer() {
        return SampleParent.this;
    }
}