如果可能的话,我非常想提供一种替代架构!与您所拥有的没什么不同。
首先,我们将定义一些接口。
public interface Named {
String getName();
}
现在,这意味着您可以有许多具体的类,但是只要它们实现了此接口,您就会知道(并且Java编译器会知道)它们具有getName
方法。
接下来,让我们更新您的类以实现此接口。
public class A implements Named {
public String getName() {
return "A";
}
}
您可以对类B
,C
...等执行此操作。
现在,您的方法返回类型可以设置为Named
,即:
public class ClassSelector{
public static Named getClassByName(String nameOfClass){
if(nameOfClass.equals("A")){ return new A();}
if(nameOfClass.equals("B")){ return new B();}
}
}
您可以像这样访问响应:
Named response = ClassSelector.getClassByName("A").getName();
,
正如Eran所建议的,它只能是Object类型,因为除了Object之外,它们没有公共的超类。如果您不想使用Object类,则可以创建一个无主体的接口,并在两个(或多个类)中实现它,这可以作为您的返回类型。
调用该方法后,您可以使用instanceof;查找返回对象的特定类型。
,
您要尝试做的事情称为Factory Pattern。
假设您建议使用Widgets
,
- 根据Christopher的回答,引入一个
Widget
接口并让A
和B
实现Widget
- 将
ClassSelector
重命名为WidgetFactory
- 将方法
getClassByName
重命名为create
,使其变为非静态并返回Widget
实例
这与常见的Java名称约定更加一致,因此使大多数开发人员都容易理解您的代码。
如果要使工厂保持静态,这当然是可能的,但是由于您无法在测试中将其切换到其他工厂,因此这可能会使代码的测试性较差。如果A和B是很重的对象,并且它们带有很多外部依赖关系,您可能要排除掉,则这是有问题的。
如果要考虑可测试性,您甚至可以考虑让工厂实现WidgetFactory
接口...
,
首先,请注意,对于字符串比较,您不必使用“ ==”(问题出在nameOfClass == "A"
中,依此类推,我仅出于完整性目的而说)。
我想提出一个基于反射的解决方案,它可能更简洁:
public interface IClass {
}
public class A implements IClass {
private String name = "A";
}
public class B implements IClass {
private String name = "B";
}
public class ClassSelector {
public static void main(String[] args) {
IClass obj = null;
try {
Class c = Class.forName("A");
obj = (IClass) c.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("Create object of type " + obj.getClass());
}
}
,
感谢所有回答我的人。原谅我,当我创建第一篇文章时,我犯了一个错误,导致误解了我的意思。现在,第一篇文章中的代码可以更好地显示我在寻找什么。
本文链接:https://www.f2er.com/2859237.html