我正在完成学校作业,我必须实施工厂模式。我已经走了很长的路,但还有最后一件事我无法工作。
我有以下课程:
//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
决赛了。不允许在课程中将final
与abstract
合并。
编辑:
所以我得到了一个提示,以保护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(){};
}
}
答案 0 :(得分:2)
添加具有默认可见性的构造函数:
public abstract class Human {
Human(){}
}
默认情况下,这只允许访问同一个包中的类,因此它被称为" package private"。
答案 1 :(得分:0)
使用构造函数的默认修饰符:
Human(){}
答案 2 :(得分:0)
请注意,无法从基类创建匿名类不是实现Factory Pattern的主要问题。该模式的目的是封装对象创建逻辑,以便可以轻松更改它,而不会影响正在实例化的类,也不会影响使用这些实例的客户端。
将静态工厂方法放入创建其子类的具体实例的基类中,由于继承以及工厂模式的目的,它会破坏类分离的目标。
我会认真考虑将您的工厂方法粘贴到一个单独的类中,例如HumanFactoryImpl
并提供相应的界面。