rai*_*yan 4 java solid-principles
我试图理解里氏替换原则,我有以下代码:
class Vehicle {
}
class VehicleWithDoors extends Vehicle {
public void openDoor () {
System.out.println("Doors opened.");
}
}
class Car extends VehicleWithDoors {
}
class Scooter extends Vehicle {
}
class Liskov {
public static void function(VehicleWithDoors vehicle) {
vehicle.openDoor();
}
public static void main(String[] args) {
Car car = new Car();
function(car);
Scooter scooter = new Scooter();
//function(scooter); --> compile error
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定这是否违反。原则上说,如果你有一个类 S 的对象,那么你可以用类 T 的另一个对象替换它,其中 S 是 T 的子类。但是,如果我写怎么办
Vehicle vehicle = new Vehicle();
function(vehicle);
Run Code Online (Sandbox Code Playgroud)
这当然会产生编译错误,因为 Vehicle 类没有 openDoor() 方法。但这意味着我不能用它们的父类Vehicle来替换VehicleWithDoors对象,这似乎违反了原则。那么这段代码是否违反了呢?我需要一个很好的解释,因为我似乎无法理解它。
你搞反了。该原则指出“如果S是 的子类型T,则T程序中的 类型的对象可以用 类型的对象替换,S而不改变该程序的任何所需属性”。
基本上, VehicleWithDoors应该在能Vehicle工作的地方工作。这显然并不意味着Vehicule应该在工作的地方工作VehiculeWithDoors。但换句话来说,您应该能够用专门化代替概括,而不影响程序的正确性。
示例违规是扩展定义操作的ImmutableLista ,其中不可变实现抛出异常。Listadd
class List {
constructor() {
this._items = [];
}
add(item) {
this._items.push(item);
}
itemAt(index) {
return this._items[index];
}
}
class ImmutableList extends List {
constructor() {
super();
}
add(item) {
throw new Error("Can't add items to an immutable list.");
}
}Run Code Online (Sandbox Code Playgroud)
接口隔离原则 (ISP) 可用于避免此处声明ReadableList接口的冲突WritableList。
传达可能不支持添加项目的另一种方式可能是添加canAddItem(item): boolean方法。设计可能不那么优雅,但它清楚地表明并非所有实现都支持该操作。
我实际上更喜欢 LSP 的这个定义:“LSP 表示每个子类必须遵守与超类相同的契约”。“合同”不仅可以在代码中定义(在我看来更好),还可以通过文档等来定义。
| 归档时间: |
|
| 查看次数: |
2507 次 |
| 最近记录: |