簡體   English   中英

從Java中的父列表調用子方法

[英]Call child methods from parent list in Java

我有一個這樣的設備父類

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);
 }

然后我有一個設備處理程序,它具有設備對象列表和一些從列表中檢索設備實例的方法

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中這是不可能的,但是也許您可以建議我如何實現結果。

我已經嘗試過訪問者模式,但是在我看來,這不是正確的模式,因為它不允許我返回值。

唯一的方法似乎是在處理程序類中為每個設備的每個值添加一個方法,如下所示

boolean getSwitchState(Device dev){
    if(dev.instanceOf(SwitchDevice)){
     SwitchDevice device = (SwitchDevice)dev;
     return device.getState();
    }else{
      throw new Exception();
}

但是它需要很多代碼,並且不安全。

我希望您能理解我的意思(我的英語水平不是很好,並且不是Java程序員的專家)。

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.將所有常見行為添加到設備基類中(或接口?)

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

如果不可避免,至少要在一個地方進行鑄造。 由於調用代碼已經期望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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM