避免instanceof和cast,超级班级可以知道孩子班级吗?

我有使用instanceof和cast的这种代码,我想避免它们:

class Vehicle {}

class Boat extends Vehicle {
    getFloating()
}

class Car extends Vehicle{
    getWheels()
}

class UseVehicle{
    void useVehicleAsCar(Vehicle vehicle){ 
// this method cant be change its parameter Vehicle,of course ;D

        if (vehicle instanceof Car){
           ((Car)vehicle).getWheels() 
        }
    }
}

解决方案可以如下:

abstract class Vehicle {
    Car asCar(){return null;}
    Boat asBoat(){return null;}
}

class Boat extends Vehicle {
    getFloating(){};
    Boat asBoat(){return this};

}

class Car extends Vehicle{
    getWheels(){}
    Car asCar(){return this;}
}

class UseVehicle{
    void useVehicleAsCar(Vehicle vehicle){ 
// accept in exemple that object param is an instance of Car

        vehicle.asCar().getWheels(); 
    }
}

但是现在车辆班级认识孩子....如果我要上公交车班级,我必须在超级班级中添加方法

你有更好的东西吗?

piaodongdeyun1225 回答:避免instanceof和cast,超级班级可以知道孩子班级吗?

这里的第一个解决方案是摆脱Vehicle类。它没有定义CarBoat之间的共同契约。
换句话说,Vehicle与其子类的关系没有比java.lang.Object与其相同子类的关系有用。


现在,由于您不能更改useVehicleAsCar的签名,因此您别无选择,只能在该方法的实现中检查参数的运行时类。 您可以使用特定的子类型重载此方法,但是由于您将Vehicle作为参数是有原因的(您无法更改该参数),因此这似乎毫无疑问。 / p>

当然,有许多不合需要的方法来检查参数的具体类型,而选择哪种参数主要成为优先考虑的问题。 会坚持使用instanceof,因为与asBoat / asCar相比,它保持清晰并保持Vehicle的“合同”几乎没有(甚至更多)不必要的概念。

本文链接:https://www.f2er.com/3101236.html

大家都在问