我的问题的示例如下所示。两个类Car
和Bike
具有相同的字段( wheel
和 bodyColor
)。
在类里面AssembleVehicle
,方法getDetails
Car
几乎重复和Bike
。有没有办法消除冗余或提高编码标准?
class Vehicle {
Car car;
Bike bike;
//setter & getter
}
class Car {
String wheel;
String bodyColor;
//setter & getter
}
class Bike {
String wheel;
String bodyColor;
//setter & getter
}
class AssembleVehicle {
public void init(Vehicle v) {
getDetails(v.getCar);
getDetails(v.getBike);
}
private void getDetails(Car c) {
String wheel = c.wheel;
String bodyColor = c.bodyColor;
}
private void getDetails(Bike c) {
String wheel = c.wheel;
String bodyColor = c.bodyColor;
}
}
这里,我们如何删除 getDetails
的代码冗余?。我们可以只使用这个方法一次吗?
我对泛型的理解是:泛型允许您为您正在使用的任何类型自定义“泛型”方法或类。例如,假设您有一个将两个数字相加的方法。为了使用类型本身,您可能必须创建此方法的多个版本。
最佳答案
以这种方式思考 OOP 的重点是错误的。即使您解决了最初的问题,即拥有一辆内部装有汽车和自行车的车辆,带有车轮和 bodyColor 字段的车辆父类(super class)的“改进”模型也可能会被破坏(取决于您正在工作的实际领域) 。例如,自行车车轮和汽车车轮有很大不同,而雪橇是没有任何轮子的车辆。乍一看相似的事物并不总是适合纳入 super 类的候选者。
问题是,我们很容易假设,如果一个类别的两个示例具有一些共同的特征,那么这些特征对于该类别的所有成员都存在(顺便说一句,这种概括的倾向也可能是许多问题的原因社会)。
OOP 的力量并非来自提取父类(super class)(如 Vehicle)和“重用”某些字段。直接子类化是一种非常严厉的措施,不应轻易应用,因为它意味着所有当前和 future 的子类必须继承父类(super class)的完整契约(数据和行为)。一旦您想要添加新的子类并被迫做出异常(exception),您就知道模型是错误的。到那时改变它将会影响所有现有的子类。事实上,直接子类化几乎总是违反 open-closed principle , SOLID design principles 组中的第二个.
一种更灵活的方法是提取接口(interface)来封装类类别的某些方面:
interface Wheeled {
String getWheels();
}
class Car implements Wheeled {
private String wheels;
@Override
public String getWheels() {
return wheels;
}
}
class Bike implements Wheeled {
private String wheels;
@Override
public String getWheels() {
return wheels;
}
}
如果您只对轮子感兴趣,这将允许对汽车和自行车进行相同的处理:
List<Wheeled> wheeledVehicles = new ArrayList<>();
wheeledVehicles.add(new Car());
wheeledVehicles.add(new Bike());
String firstWheels = wheeledVehicles.get(0).getWheels());
如果您对车身颜色,甚至车轮和车身颜色感兴趣,您可以自由地使用界面:
interface Wheeled {
String getWheels();
}
interface Coloured{
String getBodyColour();
}
interface WheeledAndColoured extends Wheeled, Coloured {}
这允许:
List<WheeledAndColoured> wheeledAndColouredVehicles = new ArrayList<>();
wheeledAndColouredVehicles.add(new Car());
wheeledAndColouredVehicles.add(new Bike());
WheeledAndColoured first = wheeledAndColouredVehicles.get(0);
String firstWheels = first.getWheels());
String firstColour = first.getBodyColour());
如果你真的愿意,你可以将wheels字段提取到一个父类(super class)中,但是直接的 yield 是有限的。私有(private)字段是一个实现细节,将它们拉入父类(super class)当然不是那种会产生很大影响的重用类型。同时,它会在这些类之间创建非常强的依赖关系,并使 future 的更改变得更加困难。
也许如果您需要实现一些与轮子相关的“复杂”共享逻辑,那么是时候创建 Wheels 类了:
class Wheels {
private String type;
private int number;
private BigDecimal price;
public BigDecimal getReplacementCosts() {
return price.multiply(BigDecimal.valueOf(number));
}
}
现在 Car 类可以与 Wheels 类协作作为其字段之一:
class Car implements Wheeled {
private Wheels wheels;
@Override
public String getWheels() {
return wheels.getType();
}
public BigDecimal getMaintenanceCosts() {
return wheels.getReplacementCosts();
}
}
请注意,因为我们没有将 Car 和 Bike 与公共(public)父类(super class)绑定(bind)在一起,所以我们不会被迫更改 Wheeled 接口(interface)或 Bike 类。如果您想将车轮逻辑添加到 Bike 中,那么您可以轻松地做到这一点,但您不会被迫这样做。如果车轮字段位于共享父类(super class) Vehicle 中,那么您就会这样做。
所以座右铭是:优先考虑协作而不是扩展,因为它更加灵活。
关于java - 我们如何通过使用泛型/任何其他方式删除代码冗余/改进代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70272726/