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



我正在做一个学校作业,必须在其中实施工厂模式。我走了很长一段路,但是我无法开始工作的最后一件事。

我有以下类:

//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的类。这是我的问题:在test.java中,我想让不可能做以下操作:

Human h = new Human(){};

即创建人类的匿名子类。不幸的是,这条代码线运行良好,并创建了一个匿名子类。如何使这条代码无法执行/无法镇压?

ps。我已经尝试完成Human最终。不允许将finalabstract组合组合。

编辑:

所以我得到了使人类构造函数受到保护的技巧。这是更改后的样子:

//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(){}    
}

默认情况下,这仅允许在同一软件包中访问类,因此被称为"软件包私有"。

使用构造仪的默认修饰符:

Human(){}

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

将静态工厂方法放入基础类中,该基类创建其子类的具体实例,这是由于继承和工厂模式的目的而击败了班级分离的目标。

我会认真考虑将您的工厂方法粘贴到单独的类中,例如HumanFactoryImpl并提供相应的接口。

最新更新