我有以下基类和派生类:
public abstract class Drone {
public void Drone(){}
public abstract boolean commonFunc();
}
public class DroneMain extends Drone {
@Override
public boolean commonFunc(){
return false;
}
public boolean droneMainFunc(){
return true;
}
}
public class DroneOther extends Drone {
@Override
public boolean commonFunc(){
return true;
}
public boolean droneOtherFunc(){
return false;
}
}
public class DroneMgr {
public enum DroneType {MAIN, OTHER}
public Drone getDrone(DroneType type){
if (type.equals(DroneType.MAIN))
return new DroneMain();
else
return new DroneOther();
}
}
调用这些类的代码如下:
private DroneManager droneManager;
private Drone drone;
droneManager = new DroneManager();
drone = droneManager.getDrone(DroneManager.DroneType.MAIN);
boolean value = drone.droneMainFunc();
我的问题涉及以下几行:
drone = droneManager.getDrone(DroneManager.DroneType.MAIN);
boolean value = drone.droneMainFunc();
如何制作它以便我可以从无人机对象调用droneMainFunc()?
否则,如果我在运行时之前不知道它的类型,我该怎么做呢。 如果我不能使用Drone(无人机实例),那么直到运行时我才会知道,我将不得不创建一个DroneMain对象和一个DroneOther对象,然后根据返回的类型分配/转换一个。我想避免这种情况,因为我确信有更好的模式。
答案 0 :(得分:0)
最简单的方法是使用instanceof
运算符。
drone = droneManager.getDrone(DroneManager.DroneType.MAIN);
if (drone instanceof DroneMain) {
((DroneMain)drone).droneMainFunc();
} ...
但我会考虑在你的Drone
类中包含另一个抽象方法,它只会调用正确的函数。这是因为你似乎想在它的实际类上独立执行一个函数。如果是这样,你应该在抽象类中包含另一个常用函数,两个实现都可以使用它们作为Drone#commonFunc
。
public abstract class Drone {
public void Drone(){}
public abstract boolean commonFunc();
public abstract boolean doSomething();
}
public class DroneMain extends Drone {
@Override
public boolean commonFunc(){
return false;
}
@Override
public boolean doSomething() {
return droneMainFunc();
}
public boolean droneMainFunc(){
return true;
}
}
public class DroneOther extends Drone {
@Override
public boolean commonFunc(){
return true;
}
@Override
public boolean doSomething() {
return droneOtherFunc();
}
public boolean droneOtherFunc(){
return false;
}
}
...
boolean value = drone.doSomething();
答案 1 :(得分:0)
我有两个选择:
跳过枚举并改用类和泛型。这允许您在 DroneMgr 中对类型进行断言,并返回正确的类型。
public class DroneMgr {
public <T extends Drone> T getDrone(Class<T> type) {
if(DroneMain.class.equals(type)) {
// Need to cast to T, but we already know that T is DroneMain
return (T) new DroneMain();
} else if (DroneOther.class.equals(type)) {
return (T) new DroneOther();
} else {
throw new IllegalArgumentException("Unknown Drone class " + type);
}
}
}
使用:
DroneMain drone = droneManager.getDrone(DroneMain.class); // No need to cast
boolean value = drone.droneMainFunc();
另一个选择是使用策略模式并直接在枚举中实现功能,这样可以轻松添加新类型。
public enum DroneType {
MAIN {
@Override
public boolean handle() {
return new DroneMain().droneMainFunc();
}
},
OTHER {
@Override
public boolean handle() {
return new DroneMain().droneOtherFunc();
}
};
public abstract boolean handle();
}
然后你就做了:
boolean value = DroneType.MAIN.handle();
如果您不是在枚举中编写实现的粉丝,您可以将功能分解为单独的类,这些类都实现了一个公共接口,并且只是在枚举中引用该实例。
public interface DroneHandler {
boolean handle();
}
public class DroneMainHandler implements DroneHandler {
@Override
public boolean handle() {
return new DroneMain().droneMainFunc();
}
}
public class DroneOtherHandler implements DroneHandler {
@Override
public boolean handle() {
return new DroneOther().droneMainFunc();
}
}
public enum DroneType {
MAIN(new DroneMainHandler()),
OTHER(new DroneOtherHandler());
public final DroneHandler handler;
private DroneType(final DroneHandler handler) {
this.handler = handler;
}
}
用法然后变为:
boolean value = DroneType.MAIN.handler.handle();