当枚举属性由于新继承而始终具有相同的值时,我是否应该保留它?
Should I keep an enum attribute when it has always the same value as a result of a new inheritance?
我有这些 classes:
enum Brand {
FORD, FERRARI, TESLA, RENAULT;
}
public class Car {
Brand brand;
String plate;
...
}
//getters and setters
想象一下,出于某种原因,我需要为两个新的 class 将 Car 设为超级class:CombustionCar 和 ElectricCar。新要求之一是 ElectricCar 的品牌属性必须始终是 TESLA 值,而不是任何其他值。
我想到了一些解决方案:
- 我可以在 superclass 汽车上保留品牌属性,并让 ElectricCar 构造函数设置 TESLA 品牌。但是这种方式可以让我在创建对象后设置一个新品牌
public class ElectricCar extends Car {
public ElectricCar(...){
super(Brand.TESLA, ...);
}
ElectricCar ec = new ElectricCar(...);
ec.setBrand(Brand.FORD);
- 我可以从 superclass 中取出 Brand attr 并将其设置在两个 subclasses 上,但在 ElectricCar 中将其设置为带有 final 的 class 属性,这样任何人都可以能够设置一个新值
public class ElectricCar extends Car {
public static final Brand brand = Brand.TESLA;
...
}
public class CombustionCar extends Car {
private Brand brand;
...
}
- 避免继承并使用组合,但是有了这个我将无法使用,例如,包含以下两者的列表:
public class ElectricCar {
private Car car;
private Brand brand = Brand.TESLA;//with no setter
...
}
public class CombustionCar {
private Car car;
private Brand brand;
...
}
我正在寻求最优雅、最可维护的解决方案,我认为它们中的任何一个都可以很好地解决我的问题。
您的第一个解决方案不正确,因为您需要电动汽车的不可编辑品牌。
你的第二个解决方案根本不起作用,除非你覆盖品牌字段的 getter 和 setter 以使用你的静态字段,这不是“优雅和可维护的”
您的第三个解决方案没有使用面向对象的概念。
我会使用的一个简单解决方案是让字段品牌及其 getter 在 Car superclass 中,但我只会在 CombustionCar [=] 中定义 setter 31=]。
或者,如果你扩展你的模型,你可以创建一个中间抽象 superclass "FreeBrandCar" 来实现 setter.
在 CombustionCar 中使用 setter 的解决方案
abstract public class Car {
protected String brand;
protected Car(final String b) {
this.brand = b;
}
public String getBrand() {
return this.brand;
}
}
public class ElectricCar extends Car {
public ElectricCar() {
super("Tesla");
}
}
public class CombustionCar extends Car {
public CombustionCar(final String b) {
super(b);
}
public void setBrand(final String b) {
this.brand = b;
}
}
具有中间体的解决方案class
abstract public class Car {
protected String brand;
protected Car(final String b) {
this.brand = b;
}
public String getBrand() {
return this.brand;
}
}
abstract public class FreeBrandCar extends Car {
public FreeBrandCar (final String b) {
super(b);
}
public void setBrand(final String b) {
this.brand = b;
}
}
public class ElectricCar extends Car {
public ElectricCar() {
super("Tesla");
}
}
public class CombustionCar extends FreeBrandCar {
public CombustionCar(final String b) {
super(b);
}
}
它尊重您的要求:
public void test() {
ElectricCar ec = new ElectricCar();
ec.setBrand("..."): // Doesn't compile
CombustionCar cc = new CombustionCar("Ford"); // OK
cc.setBrand("Fiat"); // OK
Arrays.asList(ec, cc)
.stream()
.forEach(car -> System.out.println(car.getBrand())); // prints Tesla and Fiat
}
我有这些 classes:
enum Brand {
FORD, FERRARI, TESLA, RENAULT;
}
public class Car {
Brand brand;
String plate;
...
}
//getters and setters
想象一下,出于某种原因,我需要为两个新的 class 将 Car 设为超级class:CombustionCar 和 ElectricCar。新要求之一是 ElectricCar 的品牌属性必须始终是 TESLA 值,而不是任何其他值。 我想到了一些解决方案:
- 我可以在 superclass 汽车上保留品牌属性,并让 ElectricCar 构造函数设置 TESLA 品牌。但是这种方式可以让我在创建对象后设置一个新品牌
public class ElectricCar extends Car {
public ElectricCar(...){
super(Brand.TESLA, ...);
}
ElectricCar ec = new ElectricCar(...);
ec.setBrand(Brand.FORD);
- 我可以从 superclass 中取出 Brand attr 并将其设置在两个 subclasses 上,但在 ElectricCar 中将其设置为带有 final 的 class 属性,这样任何人都可以能够设置一个新值
public class ElectricCar extends Car {
public static final Brand brand = Brand.TESLA;
...
}
public class CombustionCar extends Car {
private Brand brand;
...
}
- 避免继承并使用组合,但是有了这个我将无法使用,例如,包含以下两者的列表:
public class ElectricCar {
private Car car;
private Brand brand = Brand.TESLA;//with no setter
...
}
public class CombustionCar {
private Car car;
private Brand brand;
...
}
我正在寻求最优雅、最可维护的解决方案,我认为它们中的任何一个都可以很好地解决我的问题。
您的第一个解决方案不正确,因为您需要电动汽车的不可编辑品牌。
你的第二个解决方案根本不起作用,除非你覆盖品牌字段的 getter 和 setter 以使用你的静态字段,这不是“优雅和可维护的”
您的第三个解决方案没有使用面向对象的概念。
我会使用的一个简单解决方案是让字段品牌及其 getter 在 Car superclass 中,但我只会在 CombustionCar [=] 中定义 setter 31=]。 或者,如果你扩展你的模型,你可以创建一个中间抽象 superclass "FreeBrandCar" 来实现 setter.
在 CombustionCar 中使用 setter 的解决方案
abstract public class Car {
protected String brand;
protected Car(final String b) {
this.brand = b;
}
public String getBrand() {
return this.brand;
}
}
public class ElectricCar extends Car {
public ElectricCar() {
super("Tesla");
}
}
public class CombustionCar extends Car {
public CombustionCar(final String b) {
super(b);
}
public void setBrand(final String b) {
this.brand = b;
}
}
具有中间体的解决方案class
abstract public class Car {
protected String brand;
protected Car(final String b) {
this.brand = b;
}
public String getBrand() {
return this.brand;
}
}
abstract public class FreeBrandCar extends Car {
public FreeBrandCar (final String b) {
super(b);
}
public void setBrand(final String b) {
this.brand = b;
}
}
public class ElectricCar extends Car {
public ElectricCar() {
super("Tesla");
}
}
public class CombustionCar extends FreeBrandCar {
public CombustionCar(final String b) {
super(b);
}
}
它尊重您的要求:
public void test() {
ElectricCar ec = new ElectricCar();
ec.setBrand("..."): // Doesn't compile
CombustionCar cc = new CombustionCar("Ford"); // OK
cc.setBrand("Fiat"); // OK
Arrays.asList(ec, cc)
.stream()
.forEach(car -> System.out.println(car.getBrand())); // prints Tesla and Fiat
}