我有一个SuperClass Named Vehicle,其中有一个名为Chain的字段/方法。现在我有 2 个子类作为汽车和自行车。现在我们知道自行车需要链条,但汽车不需要。那么在Java中,我们如何确保链属性只在自行车CLass中继承,而不在汽车类中继承呢?现在我还有其他类,比如自行车,它也需要链属性......那么怎么办呢?
你把它分开了
Vehicle
* Other fields
MotorizedVehicle extends Vehicle
* Specialized fields
NotMotorizedVehicle extends Vehicle
* Chain
Car extends MotorizedVehicle
Bike extends NotMotorizedVehicle
那么我们如何确保
Chain
属性只在Bike
类中继承,而不在Car
类中继承
你不能。
每个子类都继承其超类的所有公共字段和方法。 如果没有,那么Java将无法正确实现子类型/Liskov替换原则,这是面向对象编程的核心。
正确的解决方案是不要使Vehicle
的Chain
属性。
在方法的情况下,Java确实为您提供了另一种选择;例如
public class Tram extends Vehicle {
...
public SteeringWheel getSteeringWheel() {
throw new UnsupportedOperationException(
"A tram has no steering wheel");
}
}
。但它的设计很差,如果可能的话,你应该避免它。
在 Bike 中声明它所属的 Chain
成员字段。 你所要求的是不可能的,也不是真的必要。
如果你的Vehicle
类具有Chain
属性,那么所有扩展Vehicle
类都将继承chain
属性。 没有例外,因为这就是 OOP 中的继承。您可以选择不Car
类中使用链属性,Bike
您可以使用它。
此外,正如 Jeroen 指出的那样,您也可以像这样实现类设计,在这种情况下我通常会这样做。
将chain
成员放在Vehicle
类中是糟糕的设计,因为并非所有Vehicle
都有chain
。
code re-usability
而将成员放在不应该的地方是糟糕的设计。
如果你真的需要避免代码重复,定义一个名为ChainedVehicle extends Vehicle
的抽象类并向其添加chain
成员,现在你有一个合适的链式车辆超类。
如果您的车辆可以组织为层次结构,请使用Jeroen Vannevel的答案。如果您需要更大的灵活性,请考虑一组表示车辆功能的接口。
HasChain将由任何链条驱动车辆实现,包括自行车。
HasWheels将由MotorBike,Bike,Car和HorseDrawnCarriage实现,但不能由DogSled实现。
机动化将由摩托车和汽车实施。
AnimalDraw将由HorseDrawCarriage和DogSled实现。