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

时间:2015-05-12 15:40:44

标签: java factory final

我正在完成学校作业,我必须实施工厂模式。我已经走了很长的路,但还有最后一件事我无法工作。

我有以下课程:

//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构造函数。这是改变后的样子:

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

3 个答案:

答案 0 :(得分:2)

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

public abstract class Human {        
    Human(){}    
}

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

答案 1 :(得分:0)

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

Human(){}

答案 2 :(得分:0)

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

将静态工厂方法放入创建其子类的具体实例的基类中,由于继承以及工厂模式的目的,它会破坏类分离的目标。

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