Factory-style Enum as an internal Enum in Java

I tried to implement a factory template with Enum as an internal Enum, but that didn't work. Is there any solution without splitting the internal Enum into a new file? In other words, is it possible to use the factory template of the internal Enum template?

The code is below.

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

Compilation error message below

$ 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
+6
source share
3 answers

To create an instance without a static inner class ( InnerChildA, InnerChildBetc.), you need to qualify an instance of the instance with an instance of the enclosing type ( SampleParent). You should do something like this:new ExternalClass().new InternalClass()

SampleParent InnerChildEnum getInstance() .

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 sampleParent.new InnerChildA();
        }
    },
    CHILD_B {
        @Override
        public InnerChild getInstance() {

            return sampleParent.new InnerChildB(); // compile error
        }
    },
    CHILD_C {
        @Override
        public InnerChild getInstance() {
            return sampleParent.new InnerChildC();
        }
    };

    private static SampleParent sampleParent = new SampleParent();

    public abstract InnerChild getInstance();
}
+2

, SampleParent.

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

e. . return new InnerChildA(); .

+5

The code for improvements is here, in the case.

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 foo
        }
    }
    private class InnerChildB extends InnerChild {
        public void doSomething() {
            System.out.println(foo);  // refer sampleParent.foo, not original foo
        }
    }
    private class InnerChildC extends InnerChild {
        public void doSomething() {
            System.out.println(outer().foo);  // refer sampleParent.foo, not original 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;
    }
}
0
source

Source: https://habr.com/ru/post/1015968/


All Articles