This question already has answers here:
Java inner class and static nested class
                                
                                    (26个答案)
                                
                        
                                2年前关闭。
            
                    
public class DataFactory {

    class SYNOP implements IDataSources {}
    class WRF implements IDataSources {}

    public abstract class Factory {
        public abstract IDataSources CreateModel();
    }

    public class SYNOPFactory extends Factory {

        @Override
        public IDataSources CreateModel() {
            return new SYNOP();
        }
    }

    public class WRFFactory extends Factory {

        @Override
        public IDataSources CreateModel() {
            return new WRF();
        }
    }

    public static void main(String[] args) {

        Factory factory = new WRFFactory();

    }
}


而且我收到这样的消息错误:


  无法访问类型为DataFactory的封闭实例。必须符合条件
  使用封闭的DataFactory类型实例进行分配(例如
  x.new A(),其中x是DataFactory的实例)。


我做错了什么?

问候

最佳答案

SYNOPFactoryWRFFactory被声明为DataFactory的内部类。

这意味着它们的实例需要一个DataFactory实例。
您可以实例化它们,例如

Factory factory = new DataFactory().new WRFFactory();


但是实际上,将它们设置为内部类并不是很有意义。
为什么您需要将它们的实例与DataFactory紧密地结合在一起?

您应该在它们自己的类文件中声明它们。
并在自己的班级中提取其他班级。否则,您将遇到同样的问题。



请注意,如果要对客户端隐藏IDataSources实现,则可以将其子类声明为创建其实例的factory子类的私有类成员:

public class SYNOPFactory extends Factory {

    private class SYNOP implements IDataSources {
    }

    @Override
    public IDataSources CreateModel() {
       return new SYNOP();
    }
}

public class WRFFactory extends Factory {

    private class WRF implements IDataSources {
    }

    @Override
    public IDataSources CreateModel() {
       return new WRF();
    }
}


这样,当您通过interface进行编程时,它将可以正常编译:

Factory factory = new WRFFactory();
IDataSources dateSources = factory.CreateModel();


但这不会像现在WRFWRFFactory类私有:

WRF wrf = new ...;




另请注意,不需要创建工厂的多个实例。
重复new DataFactory()习惯用法将通过创建许多工厂实例来完成。

工厂可以创建对象的多个实例,但是为什么需要工厂的多个实例呢?
一个可以创建您需要的所有对象。
因此,您应该具有工厂的单例实例。
为此,可以使用单例DP或依赖项注入(更好)。

依赖注入需要一个DI框架。您似乎没有使用它。
解决方法是,在纯Java中,您可以实现一个渴望的Singleton(感谢Bill Pugh),例如:

public class WRFFactory extends Factory {

    private class WRF implements IDataSources {
    }

    private static WRFFactory instance = new WRFFactory();

    private WRFFactory(){
    }

    public static WRFFactory getInstance(){
       return instance;
    }
    @Override
    public IDataSources CreateModel() {
       return new WRF();
    }
}


现在,您可以通过以下方式创建您的IDataSources实例:

IDataSources datasources = WRFFactory.getInstance().CreateModel();

09-30 14:18
查看更多