我有像这样的设备父类
class Device{
int id;
public Device(int id);
}
和一些子设备
class SwitchDevice extends Device{
boolean state;
public SwitchDevice(int id);
boolean getState();
void setState(boolean state);
}
class LightDevice extends SwitchDevice{
int value;
public SwitchDevice(int id);
int getValue();
void setValue(int value);
}
然后我有一个Device处理程序,它有一个Device对象列表和一些从列表中检索设备实例的方法
class DeviceHandler {
private List<Device> deviceList;
public DeviceHandler() {
deviceList = new ArrayList<Device>();
}
public Device getById(int devId);
}
我想知道如何从此列表中调用childs方法 我的意思是像
Device dev = deviceHandler.getById(0);
boolean state = dev.getState;
我知道在java中这是不可能的,但也许你可以建议我如何实现de result。
我尝试了访问者模式,但在我的情况下不是正确的,因为它不允许我返回值。
唯一的方法似乎是在处理程序类中添加一个方法,为每个设备的每个值添加这样的
boolean getSwitchState(Device dev){
if(dev.instanceOf(SwitchDevice)){
SwitchDevice device = (SwitchDevice)dev;
return device.getState();
}else{
throw new Exception();
}
但它需要大量代码并且不安全。
我希望你明白我的意思(我的英语不是很好,而不是专业的java程序员)。
答案 0 :(得分:1)
<强> 1。使用instanceof
你已经使用了instanceof但我不明白为什么这里需要很多代码。这很安全。
Device dev = deviceHandler.getById(0);
if (dev instanceof SwitchDevice) {
((SwitchDevice)dev).getState()
}
// More check instanceof
<强> 2。使用反思
try {
// Get public getState()
Method m = dev.getClass().getMethod("getState");
Boolean state = (Boolean )m.invoke(dev);
} catch (NoSuchMethodException ex) {
// dev is not SwitchDevice
}
第3。将所有常见行为添加到设备基类(OR接口?)
class Device{
// ...
public boolean getState() {
throw new UnsupportedOperationException();
}
public int getValue() {
throw new UnsupportedOperationException();
}
}
class SwitchDevice extends Device {
// ...
@Override
public boolean getState() {
return this.state;
}
}
class LightDevice extends SwitchDevice {
// ...
@Override
public int getValue() {
return this.value;
}
}
对于此解决方案。您需要了解UnsupportedOperationException
答案 1 :(得分:0)
如果处理铸造是不可避免的,至少在一个地方进行。由于调用代码已经预期来自getById
方法的特定子类,因此将该方法更新为通用方法并在其中进行所有转换:
public <T extends Device> Optional<T> getById(Class<T> deviceType, int devId){
Device d = deviceList.get(devId);
if ( d == null || !deviceType.isInstance(d) ) return Optional.empty();
return Optional.of( deviceType.cast(d) );
}
然后像这样称呼它:
Optional<SwitchDevice> sd = deviceHandler.getById(SwitchDevice.class, 1);
boolean state = sd.orElseThrow( () -> new Exception() ).getState();
或一个班轮:
boolean state = deviceHandler.getById(SwitchDevice.class, 1)
.orElseThrow( () -> new Exception() )
.getState();