Ваши подклассы не обеспечивают различного поведения только различного данных .
Следовательно, вы не должны использовать разные подклассы, только разные аргументы.
Я бы предложил добавить метод getCar в базовый вариант и использовать его как заводской метод.
Добавьте свойства «Цвет» и «Цилиндр» и загрузите их из ... в любое удобное для вас место, это может быть база данных, файл свойств, фиктивный объект, из Интернета, из космического пространства ... и т. Д.
До:
Car car = new CarOne(2009); // Using new to get different data....
carObject.getColor();
carObject.getNumCylinders();
После того, как:
class Car {
// Attributes added and marked as final.
private final Color color;
private final int numberCylinders;
// original
private final int manufacteredYear;
public static Car getCar( String spec, int year ) {
return new Car( year,
getColorFor( spec ) ,
getCylindersFor(spec) );
}
// Make this private so only the static method do create cars.
private Car( int year, Color color, int cylinders ) {
this.manufacturedYear = year;
this.color = color;
this.numberCylinders = cylinders;
}
// Utility methods to get values for the car spec.
private static final getColorFor( String spec ) {
// fill either from db, xml, textfile, propertie, resource bundle, or hardcode here!!!
return ....
}
private static final getCylindersFor( String spec ) {
// fill either from db, xml, textfile, propertie, resource bundle, or hardcode here!!!
return ....
}
// gettes remain the same, only they are not abstract anymore.
public Color getColor(){ return this.color; }
public int getNumCylinders(){ return this.numberCylinders; }
}
Таким образом, вместо того, чтобы создавать новый автомобиль напрямую, вы получите его с помощью метода getCar:
Car car = Car.getCar("CarOne", 2009 );
....
Я бы не советовал вам делать ваш автомобиль "изменчивым", так как он может вызвать незначительные нежелательные побочные эффекты (поэтому я отмечаю атрибуты как окончательные). Поэтому, если вам нужно «модифицировать» свой автомобиль, вам лучше назначить новые атрибуты:
Car myCar = Car.getCar("XYZ", 2009 );
.... do something with car
myCar = Car.getCar("Modified", 2009 );
//-- engine and color are "modified"
Кроме того, вы даже можете нанести на карту всю машину, чтобы использовать только один экземпляр.
При этом вам не нужно добавлять сеттеры в ваш код. Единственное, что вам нужно сделать, это найти и заменить
Car xyz = new WhatEver( number );
Для
Car xyz = Car.getCar("WhatEver", number );
А остальная часть кода должна работать без изменений.