gpt4 book ai didi

java - 试图理解 Liskov 替换原理

转载 作者:行者123 更新时间:2023-12-03 23:03:28 26 4
gpt4 key购买 nike

我试图理解 里氏代换原理 ,我有以下代码:

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

我不确定这是否违反它。原理是,如果你有一个类 S 的对象,那么你可以用另一个类 T 的对象替换它,其中 S 是 T 的子类。但是,如果我写
Vehicle vehicle = new Vehicle();
function(vehicle);
这当然会产生编译错误,因为 Vehicle 类没有 openDoor() 方法。但这意味着我不能用其父类 Vehicle 替换 VehicleWithDoors 对象,这似乎违反了原则。那么这段代码是否违反了它?
我需要一个很好的解释,因为我似乎无法理解它。

最佳答案

你把它弄反了。该原则指出"if S is a subtype of T , then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program" .
基本上,VehicleWithDoors应该在哪里工作 Vehicle作品。这显然并不意味着 Vehicule应该在哪里工作 VehiculeWithDoors工作。然而换句话说,你应该能够用特化代替泛化而不影响程序的正确性。
示例违规将是 ImmutableList延长 List定义了 add操作,其中不可变实现抛出异常。

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.");
}
}

接口(interface)隔离原则 (ISP) 可用于避免此处的违规行为,您可以在此处声明 ReadableListWritableList接口(interface)。
另一种表达可能不支持添加项目的方式是添加 canAddItem(item): boolean方法。设计可能不那么优雅,但它清楚地表明并非所有实现都支持该操作。
我实际上更喜欢 LSP 的这个定义: "LSP says that every subclass must obey the same contracts as the superclass" .
“契约(Contract)”不仅可以在代码中定义(在 IMO 时更好),还可以通过文档等来定义。

关于java - 试图理解 Liskov 替换原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64090262/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com