让我们说我想要一个MyClass类,除其他外,还有一个代表车辆的属性。
车辆可以是汽车或摩托车。
如果是汽车,我希望能够找回方向盘。
编辑:我的基本主张是摩托车没有方向盘,所以我想避免在摩托车类中使用像getSteeringWheel这样的东西。我看到两个解决方案:
问题是,从MyClass对象,要检索方向盘的类型,我必须做这样的事情:
Vehicle vehicle = getVehicle();
if (vehicle instanceof Car) {
SteeringWheel steeringWheel = ((Car) vehicle).getSteeringWheel();
}
我认为这不是很好。
Vehicle vehicle = getVehicle();
if (VehicleTypeEnum.CAR.equals(vehicle.getType())) {
SteeringWheel steeringWheel = vehicle.getSteeringWheel();
}
但是,Vehicle将是一个令人讨厌的类,因为如果对象的类型是MOTORCYCLE,则getSteeringWheel()方法没有多大意义。
哪个更好?还有其他解决方案吗?谢谢!
答案 0 :(得分:3)
避免使用instanceof
,因为它break your OOP design。相反,找到汽车和摩托车的共同点。两者都有一个转向的部分。将其提取到超类中,并在子类中实现实际的转向。
public abstract class Vehicle {
public abstract Steer getSteer();
}
public abstract class Steer {
public abstract left();
public abstract right();
}
public class Car extends Vehicle {
@Override
public SteeringWheel getSteer() {
return wheel;
}
}
public class Motorcycle extends Vehicle {
@Override
public SteeringBar getSteer() {
return bar;
}
}
(非本地人,我不确定'steer'实际上是否是英文名词)
答案 1 :(得分:1)
如果问题措辞不当,我很抱歉,但我认为在你的帮助下我设法解决了我的问题。目前我有这样的事情:
public class MyClass {
private Vehicle vehicle;
public void doStuff() {
doNonVehicleStuff();
Vehicle vehicle = getVehicle();
doRegularStuff(vehicle);
if (vehicle instanceof Car) {
SteeringWheel steeringWheel = ((Car) vehicle).getSteeringWheel();
doSteeringWheelStuff(steeringWheel);
}
}
但实际上我应该这样做:
public void doStuffWithVehicle() {
doNonVehicleStuff();
getVehicle().doStuff();
}
除了Car
之外,doStuff
覆盖doSteeringWheelStuff
方法以包含regularStuff
。
答案 2 :(得分:0)
尽可能避免使用instanceof
- 不应强迫Vehicle
类的客户端知道 Vehicle
的子类。否则,显然每当您引入Vehicle
的新子类时,您都必须查看客户端代码。
您可能希望使用Steering
来引导Car
或Bike
,因此特定的转向可以是汽车或自行车的实例。
package stackOv;
// steers a vehicle
interface Steering {
public void steer();
}
// steers a car
class SteeringWheel implements Steering {
private Car car;
public SteeringWheel(Car car) {
this.car = car;
}
@Override
public void steer() {
car.steerCar();
//and other car-specific implementation
}
}
// steers a bike
class HandleBars implements Steering {
private Bike bike;
public HandleBars(Bike bike) {
this.bike = bike;
}
@Override
public void steer() {
bike.steerBike();
//and other bike-specific implementation
}
}
public abstract class Vehicle {
public abstract Steering getSteering();
}
class Car extends Vehicle {
private SteeringWheel steeringWheel;
public Car(SteeringWheel steeringWheel) {
this.steeringWheel = steeringWheel;
}
@Override
public Steering getSteering() {
return steeringWheel;
}
public void steerCar() { /* car-specific implementation here */ }
}
class Bike extends Vehicle {
private HandleBars handleBar;
public Bike(HandleBars handleBar) {
this.handleBar = handleBar;
}
@Override
public Steering getSteering() {
return handleBar;
}
public void steerBike() { /* bike-specific implementation here */ }
}
这样,您的车辆可以使用:
class Client {
Vehicle v;
public void go() {
v.getSteering().steer();
}
}