Как обрабатывать абстрактные свойства в Java? - PullRequest
0 голосов
/ 01 июня 2018

Допустим, я хочу класс MyClass, который, помимо прочего, имеет свойство, представляющее транспортное средство.

Транспортное средство может быть автомобилем или мотоциклом.

В случае автомобиля я хочу получить его рулевое колесо.

РЕДАКТИРОВАТЬ: мое основное утверждение заключается в том, что мотоцикл не имеет рулевого колеса, поэтому я хотел быизбегайте использования чего-то вроде getSteeringWheel в классе Motorcycle.

Я вижу два решения:

  1. Абстрактный класс Vehicle, расширенный двумя классами: Car и Motorcycle

Проблема в том, что из объекта MyClass, чтобы получить тип рулевого колеса, я должен сделать что-то вроде этого:

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

, что, я полагаю, не очень хорошо.

Конкретный класс Vehicle, содержащий всётогда метод getSteeringWheel () не имеет особого смысла.

Какой из них лучше?Есть ли другое решение?Спасибо!

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Избегайте использования 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();
    }
}
0 голосов
/ 02 июня 2018

Извините, если вопрос был плохо сформулирован, но я думаю, что с вашей помощью мне удалось решить мою проблему.В настоящее время у меня есть что-то вроде этого:

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.

0 голосов
/ 01 июня 2018

Избегайте использования instanceof, так как это нарушит ваш дизайн ООП .Вместо этого найдите общее, что есть у Автомобиля и Мотоцикла.У обоих есть часть, которая делает управление.Извлеките это в суперкласс и внедрите в подклассы фактическое управление.

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» на самом деле английским существительным)

...