如何在Java中处理抽象属性?

时间:2018-06-01 16:52:57

标签: java casting properties abstract instanceof

让我们说我想要一个MyClass类,除其他外,还有一个代表车辆的属性。

车辆可以是汽车或摩托车。

如果是汽车,我希望能够找回方向盘。

编辑:我的基本主张是摩托车没有方向盘,所以我想避免在摩托车类中使用像getSteeringWheel这样的东西。

我看到两个解决方案:

  1. 由两类扩展的抽象车辆类:汽车和摩托车
  2. 问题是,从MyClass对象,要检索方向盘的类型,我必须做这样的事情:

    Vehicle vehicle = getVehicle();
    if (vehicle instanceof Car) {
        SteeringWheel steeringWheel = ((Car) vehicle).getSteeringWheel();
    }
    

    我认为这不是很好。

    1. 包含所有内容的具体Vehicle类
    2. 然后我会做这样的事情:

      Vehicle vehicle = getVehicle();
      if (VehicleTypeEnum.CAR.equals(vehicle.getType())) {
          SteeringWheel steeringWheel = vehicle.getSteeringWheel();
      }
      

      但是,Vehicle将是一个令人讨厌的类,因为如果对象的类型是MOTORCYCLE,则getSteeringWheel()方法没有多大意义。

      哪个更好?还有其他解决方案吗?谢谢!

3 个答案:

答案 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来引导CarBike,因此特定的转向可以是汽车或自行车的实例。

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