设计原则(四)里氏替换原则

第一种定义,也是最正宗的定义:If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T,the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。

第二种定义:Functions that use pointers or references to base classes must be able to useobjects of derived classes without knowing it.
所有引用基类的地方必须能透明地使用其子类的对象。
第二种定义比较通俗,容易理解:只要有父类出现的地方,都可以用子类来替代,而且不会出现任何错误和异常。但是反过来则不行,有子类出现的地方,不能用其父类替代。
举个例子:


image.png

如果所示,Client调用CarService方法给车(Car)加油,代码如下:

public class Car {
    
    private String brand;
    
    private String color;
    
    public Car(String brand, String color){
        this.brand = brand;
        this.color = color;
    }
    
    public String getColor() {
        return color;
    }
    public String getBrand() {
        return brand;
    }
    
}

public class CarService {
    
    public void supply(Car car){
        refuel(car);
    }

    private void refuel(Car car) {
        System.out.println("refueling for "+car.getBrand()+" car ");
        
    }
}

public class ElectricCarService extends CarService {
    
    public void supply(Car car){
        charge(car);
    }

    public void charge(Car car){
        System.out.println("charge for car...");
    }
}

public class Client extends TestCase {

    private List carList = new ArrayList();
    
    public void test(){
        Car car = new Car("volkswagan","blue");
        carList.add(car);
        service();
    }
    private void service() {
        CarService supplier = new CarService();
        for (Car car : carList) {
            supplier.supply(car);
        }
        
    }
}

如代码所示,Client调用Service方法给汽车加油。如果这个时候把CarService换成子类ElectricCarService,再调用Service给汽车加油,但是子类没有加油的方法,只有充电的方法,则势必会导致原来父类给汽车加油的行为失败。即子类没办法取代父类,因此违反了里氏替换原则。
解决方法:一般是把补给的行为抽象出来,然后加油和充电作为两个实现类,分别以不同的方式补给。

你可能感兴趣的:(设计原则(四)里氏替换原则)