考虑下面的抽象类MeasurementType及其亚型Acceleration和Density:
public abstract class MeasurementType {
protected String name;
protected String[] units;
public MeasurementType() {}
public MeasurementType(String name) {
this.name = name;
}
protected void setName(String name) {
this.name = name;
}
protected String getName() {
return name;
}
protected void setUnits(String[] values) {
this.units = values;
}
}
public class Acceleration extends MeasurementType {
private String name;
public Acceleration () {
super();
}
public Acceleration(String name) {
super();
}
}
public class Density extends MeasurementType {
private String name;
public Density() {
super();
}
public Density(String name) {
super();
}
}
Run Code Online (Sandbox Code Playgroud)
对子类型的需求是什么,因为这些类中没有任何东西可以将它们区分开来(至少在我的实现中)赋予它们作为自己的实体存在的权利,但是为了示例,让我们说他们有自己的阵列包含每个不同类型的单位,所以密度将有千克,克等.加速将有英里,公里等.
最后我有这个运行类,我很快就编写了:
public class run {
public run() {}
public static MeasurementType testType() {
Acceleration a = new Acceleration("meters per second");
return (MeasurementType) a;
}
public static void main(String[] args) {
MeasurementType mt = testType();
System.out.println(mt.getClass().toString());
System.out.println(mt.getClass().getName());
String type = "acceleration";
String[] units = new String[8];
Object mType;
if(type.equals("acceleration")) {
mType = new Acceleration();
} else if(type.equals("density")) {
mType = new Density();
} else {
mType = new Object();
}
System.out.println(mType.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我遇到的问题.我正在使用字符串来确定我将实例化的类型,但问题是,默认情况下,在条件语句的末尾我实例化了Object,否则编译器会抱怨该mType变量不会被初始化.我不能创建一个MeasurementType对象,因为它是一个抽象类.
我想这更像是一个设计问题,但有没有更好的方法来确定要实例化的类?请假设它String type = "acceleration"来自下拉或某个用户界面的某个地方,我刚刚对其进行了硬编码,因为它对问题来说并不是必需的.
如果我看到它,有人可以解释这个设计错误.
Ric*_*gle 11
看看你的问题的关键,当字符串既不是"加速"也不是"密度"时该怎么办.
if(type.equals("acceleration")) {
mType = new Acceleration();
} else if(type.equals("density")) {
mType = new Density();
} else {
mType = new Object();
}
Run Code Online (Sandbox Code Playgroud)
这是否表明程序中的某些内容已经破坏,这是不可挽回的错误?在这种情况下; 抛出一个例外.
if(type.equals("acceleration")) {
mType = new Acceleration();
} else if(type.equals("density")) {
mType = new Density();
} else {
throw new RuntimeException("variable type is not a valid type, valid types are 'acceleration' and 'density'";
}
Run Code Online (Sandbox Code Playgroud)
这是你将要实现的目标; 例外是你的朋友.他们的意思是当程序错误时它尖叫到哪里和为什么然后你修复它.另一方面,静静地忽略这个问题会导致细微的错误和奇怪的行为,可能需要数天才能诊断出来.
另一方面,这是用户输入不当输入的标志吗?在这种情况下,验证输入,如果无效,则告诉最终用户并再次询问.
使用String像这样的s和if语句很可能根本就不是你想做的事情,但是假设它是你想要做的,那么这就是前进的方法(一个switch语句会稍好一些).
如果字符串不是重新计算的度量类型名称之一,则不应创建对象.您应该通过抛出异常来表示问题:
public MeasurementType fromString(String type) {
if (type.equals("acceleration")) {
return new Acceleration();
}
else if (type.equals("density")) {
return new Density();
}
else {
throw new IllegalArgumentException(type + " is not a known measurement type");
}
}
Run Code Online (Sandbox Code Playgroud)
像工厂一样的代码可能有所帮助.if equals and new Xxxx()如果您有100个子类型,则可以节省100个语句.
public abstract class MeasurementType {
protected String name;
private static final Map<String, Class<? extends MeasurementType>> typeMap = new HashMap<>();
static{
typeMap.put("accelaration", Acceleration.class);
typeMap.put("density", Density.class);
//put here if you have others
}
public static MeasurementType getMeasurement(String keyStr) throws RuntimeException {
if (typeMap.containsKey(keyStr)) {
try {
return typeMap.get(keyStr).newInstance();
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("creation failed.");
}
}
//this could be a speical exception type
throw new RuntimeException("creation failed: unknown type");
}
}
Run Code Online (Sandbox Code Playgroud)
在你的run类/方法中:
String s = "accelaration";
String s2 = "trash";
MeasurementType t = null;
try {
t =MeasurementType.getMeasurement(s);
t = MeasurementType.getMeasurement(s2); //throw ex
}catch (RuntimeException e){
//do something
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1050 次 |
| 最近记录: |