2016-11-06 5 views
1

Я хотел бы задать вопрос о проблеме, которая у меня есть. Допустим, у нас есть интерфейс под названием Vehicle.Добавление нового атрибута к существующему объекту

Тогда у нас есть класс, который реализует этот интерфейс под названием Car. Затем еще один называется Велосипед.

Теперь весь код использует эти два объекта (автомобиль, велосипед) и всякий раз, когда нужен интерфейс.

Что делать, если теперь я хочу добавить новый атрибут в класс Car, и из-за этого изменения также измените некоторые из его методов. Например, я могу расширить Car с классом Car2. Но теперь, если я хочу использовать Car2 в коде, мне придется переписать каждый метод и класс, который использует Car для нового класса, который будет использовать Car2.

Например, метод, не относящийся к классу Car.

int checkSpeed(Car c) { 
    speed = c.attributeX * 100 
} 

Теперь я хочу, чтобы этот способ мог принять Car2 и изменить способ его вычисления. Нужно ли переписывать класс и метод или есть ли более простой способ сделать это?

Имейте в виду, что я не хочу полностью изменять автомобиль, я просто хочу иметь как автомобиль, так и автомобиль2 и использовать их по требованию в тех же классах, не переписывая их все.

Спасибо!

+0

Если Car2 наследует автомобиль, это сам автомобиль –

+0

Удалось ли вам это исправить? – ItamarG3

ответ

0

, как Само Kuhmonen говорят:

Если car2 наследует от автомобиля это автомобиль самого

Я подробно , Вы сказали:

Теперь я хочу, чтобы этот метод мог принять Car2 также и изменить способ, которым он вычисляет свою скорость, . Нужно ли переписывать класс и метод или есть ли более простой способ сделать это?

Если вы не добавляете методы, но изменяете их содержимое, вы должны рассуждать программированием по интерфейсу или более общим способом путем программирования подходящим общим компонентом предка. В Java полиморфизм позволяет не набирать конкретный экземпляр при его объявлении, если более подходящим является базовый класс или интерфейс.

Здесь:

int checkSpeed(Car c) { 
    speed = c.attributeX * 100 
} 

вы можете отправить в качестве параметра автомобиля или любые подклассы него, там car2.
Таким образом, вы должны сохранить Car базовый класс в качестве объявленного типа, когда он подходит, особенно в методах, которые могут принимать тот или иной тип.

Он будет работать:

Car myCar = new Car(); 
checkSpeed(myCar); 
Car2 myCar2 = new Car2(); 
checkSpeed(myCar2); 
... 
int checkSpeed(Car c) { 
    speed = c.attributeX * 100 
} 

Это не будет компилироваться:

Car myCar = new Car(); 
checkSpeed(myCar); 
Car2 myCar2 = new Car2(); 
checkSpeed(myCar2); 
... 
int checkSpeed(Car2 c) { 
    speed = c.attributeX * 100 
} 
+0

Если у Car2 есть дополнительный атрибут, называемый a1, я смогу получить к нему доступ так: c.a1, так как c передается как автомобиль. – Ploo

+0

в ООП, вы должны избегать публичных полей без уважительной причины. – davidxxx

+0

Допустим, что checkSpeed ​​использует метод, общий для Car и Car2. Но поскольку checkSpeed ​​принимает параметр Car, даже если я передаю объект Car2, он все равно будет использовать метод в Car, а не в Car2. – Ploo

0

Вы можете проверить, если объект Car c фактически типа Car2:

int checkSpeed(Car c) { 
    if(c instanceof Car2){ 
     //do something if c is actually Car2, such as 
        use attributes that exist in Car2 but not in Car 
    else{ 
     //the regular case 
     speed = c.attributeX * 100 
    } 
} 
0

Имейте в виду, что я не хочу, чтобы полностью изменить автомобиль, я просто хочу, чтобы иметь как автомобиль и car2 и использовать их по требованию в тех же классах, не переписывая их все.

У вас уже есть сломанный дизайн, так как ваш выборочный метод нарушает самый важный принцип в ООП: Сокрытие информации. Отказ исправлять, потому что много работы будет вызывать гораздо больше работы позже, так же, как сейчас. Эта дополнительная работа будет возрастать экспоненциально и нанести вред вашим срокам ...

Например, метод, не относящийся к классу Car.

int checkSpeed(Car c) { 
    speed = c.attributeX * 100 
} 

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

Теперь я хочу этот метод, чтобы иметь возможность принимать car2 также и изменить способ вычисляет его скорость , Нужно ли переписывать класс и метод или есть ли более простой способ сделать это?

Если этот метод будет частью интерфейса Vehicle и реализован в CarBicycle) можно просто реализовать в car2 так, как вы хотите. не изменяя ничего в вашей программе.

И вот что такое ООП.Но вы получите то преимущество, только если вы знаете, и следовать его принципам ...

+0

Да, но этот метод был просто быстрым примером. Не думайте об этом методе, как в классе. Объект действительно имеет свои методы, объявленные в интерфейсе. Может быть, это был плохой пример от меня, но подумайте об этом как о методе, который не входит в класс, но использует Car, и теперь я хочу, чтобы он также использовал Car2. Или вы имеете в виду, что, поскольку он использует Car или Car2, он должен был быть внутри класса все время? – Ploo

+0

@Ploo * «Или вы имеете в виду, что, поскольку он использует Car или Car2, он должен был быть внутри класса все время?» * Именно это. –

0

Сlearer подход в этом случае будет позволить сам Vehicle объект, чтобы определить, как следует ускорить рассчитываться. Это имеет смысл, поскольку вся информация необходима для этого, которая уже инкапсулирована в класс Vehicle.

То, что я имею в виду, есть интерфейс вроде:

pulbic interface Vehicle { 
    int getSpeed(); 
} 

и реализации интерфейса. Для Car:

public class Car implements Vehicle { 
// some car stuff 
... 
    @Override 
    public int getSpeed() { 
     return carspeed; 
    } 
... 
} 

И Car2:

public class Car2 implements Vehicle { 
// some car2 stuff 
... 
    @Override 
    public int getSpeed() { 
     return car2speed; 
    } 
... 
} 

Теперь ваш метод проверки может выглядеть следующим образом:

public int checkSpeed(Vehicle v) { 
    int speed = v.getSpeed(); 
    // do the checks 
    ... 
    return someResult; 
} 

Таким образом, вы действительно не нужно знать тип само транспортное средство, чтобы иметь возможность проверить его скорость. В этом весь смысл полиморфизма.

И если вы не можете изменить существующий интерфейс, я бы предложил вам расширить исходный интерфейс Vehicle с помощью SpeedVehicle, который содержит все необходимые методы и построит на нем иерархию классов.

1

Вы можете override методы суперкласса (Car) внутри класса к югу (Car2), который называется полиморфизмом, который является одним из основных принципов объектно-ориентированного программирования. Этот принцип позволяет нам ссылаться на поведение разных классов в зависимости от фактического объекта (Car или объекта Car2), переданного во время выполнения.

Для вашей проблемы, вы можете следить за состояние картины, которые обеспечивают динамическое поведение в зависимости от типа прошедшего и реального осуществления checkSpeed(), как показано ниже:

SpeedChecker класс:

public class SpeedChecker { 
    int checkSpeed(Vehicle v) { 
    //depending upon the Vehicle type object passed, checkSpeed() will be called 
    v.checkSpeed(); 
} 
} 

Класс автомобиля:

public Car implements Vehicle { 
    int checkSpeed(Car c) { 
     //Add specific logic for Car 
    } 
} 

car2 Класс:

public Car2 implements Vehicle { 
    int checkSpeed(Car c) { 
     //Add specific logic for Car2 
    } 
} 
0

Если Car2 всегда Car и требует все поведение Car, то вам нужно сделать Car2 в Наследовать от Car. Если Car2 не всегда Car, но у них есть общий язык, то вам необходимо определить, что это общая почва, реализовать его в качестве BaseCar класса или интерфейса ICar, если реализация полностью отличается и Car вместе с Car2 должны быть унаследованы от BaseCar/ICar.

Смежные вопросы