Java 在运行时强制转换正确的子类
我有以下基类和派生类:Java 在运行时强制转换正确的子类,java,abstract-class,Java,Abstract Class,我有以下基类和派生类: public abstract class Drone { public void Drone(){} public abstract boolean commonFunc(); } public class DroneMain extends Drone { @Override public boolean commonFunc(){ return false; } public boolean dro
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();
如何使其能够从无人机对象调用drone mainfunc()
否则,如果我直到运行时才知道它的类型,我该如何做呢。
如果我不能使用Drone(Drone实例),那么直到运行时我才知道,我必须创建一个Drone主对象和一个Drone其他对象,然后根据返回的类型仅分配/强制转换一个。我希望避免这种情况,因为我确信有一种更好的模式。最简单的方法是使用
instanceof
操作符
drone = droneManager.getDrone(DroneManager.DroneType.MAIN);
if (drone instanceof DroneMain) {
((DroneMain)drone).droneMainFunc();
} ...
<>但是我想把另一种抽象方法加入到你的代码>无人机< /Cux>类中,它只需调用正确的函数即可。这是因为您似乎想要在它的实际类上独立执行一个函数。如果是这样,您应该在抽象类中包含另一个公共函数,这两个实现都可以使用,就像您的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();
我给你两个选择: 跳过枚举,改用类和泛型。这允许您在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);
}
}
}
另一种选择是使用策略模式并直接在枚举中实现功能,这使得添加新类型变得容易
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();
尽管如此,
publicGetDrone
需要返回类型。另外,通过调用DroneManager.DroneType.MAIN
您应该知道它确实返回了DroneMain
,并且您应该能够在之后强制转换它。@KevinEsche-这意味着我必须声明这两种类型,然后只实例化一种,而将另一种保留为空?添加了一个返回值Drone,thx。谢谢@Raniz。基于您使用泛型的第一个解决方案,它使我在某种程度上改变了我的问题。这让我意识到,我希望能够保留drone实例,并使用它来调用仅在drone main中定义的方法。所以,确切地说,我是这样理解的:'drone=droneManager.getDrone(droneManager.DroneType.MAIN);布尔值=drone.droneMainFunc();'
boolean value = DroneType.MAIN.handler.handle();