Java 工厂模式 - 如何防止匿名子类

Java Factory pattern - How to prevent anonymous subclasses

我正在做一项学校作业,我必须在其中实现工厂模式。我已经走了很长一段路,但还有最后一件事我无法开始工作。

我有以下 classes:

//Human.java
package human;
public abstract class Human{
    public static Human create(String namn, String pnr){
        char nastsist_char = pnr.charAt(9); // takes second last char in pnr
        String nastsist_string = Character.toString(nastsist_char);
        float siffra = Float.parseFloat(nastsist_string);   //Converts to float
        if ((siffra % 2) == 0){                 //Checks if even
            return new Woman(namn, pnr);            
        }
        else{
            return new Man(namn, pnr);
        }

    }

}

//Man.java
package human;
class Man extends Human{
    private final String pnr;
    private final String namn;

    protected Man(String n, String p){
        namn = n;
        pnr = p;
    }
    public String toString(){
        return "My name is "+namn+" and I am a man.";
    }   
}

//Woman.java
package human;
class Woman extends Human{
    private final String pnr;
    private final String namn;

    protected Woman(String n, String p){
        namn = n;
        pnr = p;
    }
    public String toString(){
        return "My name is "+namn+" and I am a woman.";
    }

}

我还有一个叫 Test.java 的 class。我的问题来了:在 Test.java 中,我想让它无法执行以下操作:

Human h = new Human(){};

即创建人类的匿名子class。不幸的是,这行代码运行得很好,并且创建了一个匿名 subclass。我怎样才能使这行代码unexecutable/uncompilable?

PS。我已经尝试将 Human 定为最终版本。不允许在 class.

中组合 finalabstract

编辑:

所以我得到了保护 Human 构造函数的提示。这是更改后的样子:

//Human.java
package human;
public abstract class Human{
    protected Human(){}

    public static Human create(String name, String idNumber){
        char secondlast_char = idNumber.charAt(9); // takes second last char in pnr
        String secondlast_string = Character.toString(secondlast_char);
        float siffra = Float.parseFloat(secondlast_string); //Converts to float
        if ((siffra % 2) == 0){                 //Checks if even
            return new Woman(name, idNumber);           
        }
        else{
            return new Man(name, idNumber);
        }
    }
}

不幸的是,在 运行 或编译 Test.java 的代码时,我仍然没有收到错误,顺便说一下,它看起来像这样:

import human.*;
public class Test{
    public static void main(String[] args){
        Human h = new Human(){};
    }
}

添加具有默认可见性的构造函数:

public abstract class Human {        
    Human(){}    
}

默认情况下,这只允许访问同一包中的 类 ,因此它被称为 "package private"。

对构造函数使用默认修饰符:

Human(){}

请注意,无法从您的基础 class 创建匿名 classes 并不是您实施 Factory Pattern 的主要问题。该模式的目的是封装对象创建逻辑,以便可以轻松更改它而不会影响正在实例化的classes 或使用这些实例的客户端。

将静态工厂方法放入创建其子 classes 的具体实例的基类 class 中也由于继承而击败了 class 分离的 objective作为工厂模式的目的。

我会认真考虑将您的工厂方法放入一个单独的 class,例如HumanFactoryImpl并提供相应的接口。