请考虑以下代码:
public abstract class Base {
public void getAnswer();
}
public class Derived1 extends Base {
public void getAnswer() {
}
}
public class Derived2 extends Base {
public void getAnswer() {
}
}
public class Main {
public final int DERIVED1 = 1;
public final int DERIVED2 = 2;
public Base b;
public static void Main() {
int which_obj = which();
switch (which_obj) {
case DERIVED1: Derived1 derived1 = new Derived1();
// construct object
b = derived1;
break;
case DERIVED2: Derived1 derived1 = new Derived1();
// construct object
b = derived2;
break;
}
b.getAnswer();
}
}
Run Code Online (Sandbox Code Playgroud)
这里我们使用switch case来决定构造什么对象,因此我们构造它并将其分配给b以便使用多态.
多态性给我们带来了什么好处?
现在有一种方法可以避免切换案例.说:有一个从int到String的映射,返回"Derived1"或"Derived2".给定包含类名称的字符串.现在我可以构造一个给定包含类名称的String的对象.就像是:
Base b = construct_obj(str);
Run Code Online (Sandbox Code Playgroud)
库调用construct_obj自动从字节码中找到obj的类,并返回对该对象的引用.然后我可以避免切换案例.通常我会有100个派生类.
好吧,你可以创建一个Map<Integer, Class<? extends Base>>然后Class.newInstance用来创建带反射的实例.它不会表现得那么好,并且有各种错误在执行时间之前不会暴露,但它会起作用.
这是一些示例代码.
import java.util.*;
abstract class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
public class Test
{
public static void main(String[] args)
{
Map<Integer, Class<? extends Base>> map =
new HashMap<Integer, Class<? extends Base>>();
map.put(1, Derived1.class);
map.put(2, Derived2.class);
int which = 2; // For example
Class<? extends Base> clazz = map.get(which);
if (clazz == null)
{
// Invalid choice. Do whatever.
}
else
{
try
{
Base base = clazz.newInstance();
// Use base
}
catch (InstantiationException e)
{
// Handle exception or whatever
}
catch (IllegalAccessException e)
{
// Handle exception or whatever
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您有一个连续的整数范围,则可以使用数组而不是地图.
另一种方法是拥有工厂实例而不是使用构造函数 - 这将是"更安全"(就不延迟错误而言),但可能会显着增加代码.(在C#中使用lambda表达式会很容易; Java 7也可以使它成为一个更好的解决方案.)
| 归档时间: |
|
| 查看次数: |
909 次 |
| 最近记录: |