有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当枚举属性作为新继承的结果始终具有相同的值时,java是否应该保留该属性?

我有以下课程:

enum Brand {
    FORD, FERRARI, TESLA, RENAULT;
}
public class Car {
    Brand brand;
    String plate;
    ...
}
//getters and setters

想象一下,出于某种原因,我需要将汽车作为两个新类的超类:燃烧汽车和电动汽车。新的要求之一是电动车的品牌属性必须始终是特斯拉价值,而不是任何其他价值。 我想到了一些解决方案:

  1. 我可以将品牌attr保留在超级车上,并让电动汽车制造商创建特斯拉品牌。但这种方式可以让我在创建对象后创建一个新品牌
public class ElectricCar extends Car {
    public ElectricCar(...){
    super(Brand.TESLA, ...);
}

ElectricCar ec = new ElectricCar(...);
ec.setBrand(Brand.FORD);
  1. 我可以将brandattr从超类中取出,并在两个子类上设置它,但在电动汽车中将其设置为带有final的类属性,这样任何人都可以设置新值
public class ElectricCar extends Car {
    public static final Brand brand = Brand.TESLA;
    ...
}
public class CombustionCar extends Car {
    private Brand brand;
    ...
}
  1. 避免继承和使用组合,但有了它,我将无法使用,例如,包含以下两个内容的列表:
public class ElectricCar {
    private Car car;
    private Brand brand = Brand.TESLA;//with no setter
    ...
}
public class CombustionCar {
    private Car car;
    private Brand brand;
    ...
}

我要求的是最优雅、最可靠的解决方案,我认为其中任何一个都能很好地解决我的问题


共 (1) 个答案

  1. # 1 楼答案

    鉴于电动汽车需要不可编辑的品牌,您的第一个解决方案是错误的

    你的第二个解决方案根本不起作用,除非你同时覆盖品牌域的getter和setter来使用你的静态域,这不是“优雅且可维护的”

    第三种解决方案没有使用面向对象的概念

    我会使用的一个简单解决方案是让field brand及其getter进入Car超类,但我只会在CombustionCar类中定义setter。 或者,如果扩展模型,可以创建一个实现setter的中间抽象超类“FreeBrandCar”

    使用CombustionCar中的设置器解决方案

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

    中间类解决方案

    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
    }