我有使用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();
}
}
但是现在车辆班级认识孩子....如果我要上公交车班级,我必须在超级班级中添加方法
你有更好的东西吗?
答案 0 :(得分:1)
这里的第一个解决方案是摆脱Vehicle
类。它没有定义Car
和Boat
之间的共同契约。
换句话说,Vehicle
与其子类的关系没有比java.lang.Object
与其相同子类的关系有用。
现在,由于您不能更改useVehicleAsCar
的签名,因此您别无选择,只能在该方法的实现中检查参数的运行时类。
您可以使用特定的子类型重载此方法,但是由于您将Vehicle
作为参数是有原因的(您无法更改该参数),因此这似乎毫无疑问。 / p>
当然,有许多不合需要的方法来检查参数的具体类型,而选择哪种参数主要成为优先考虑的问题。 我会坚持使用instanceof
,因为与asBoat
/ asCar
相比,它保持清晰并保持Vehicle
的“合同”几乎没有(甚至更多)不必要的概念。