实现Liskov替代原则

时间:2017-01-20 18:34:12

标签: java liskov-substitution-principle

我有两个班级:

public class Base {
    private final int value;
    public Base(int value){
        this.value = value;
    }
    public int getValue(){
        return value;
    }
    public Base divide(Base that){
        return new Base(getValue() / that.getValue());
    }
}

public class Extended extends Base{
    public Extended(int value){
        super(value);
    }
    @Override public Extended divide(Base that){
        return new Extended(getValue() / that.getValue());
    }
    public Extended getMax(Extended that){
        return new Extended(Math.max(getValue(), that.getValue()));
    }
}

Base b = new Base(3);
Extended c = new Extended(4);

我的目标是实现利斯科夫替代原则,但这两个类别尚未实现这一原则。我认为他们没有,因为这不起作用:

Extended d = c.getMax(b); //doesn't work
Extended e = c.getMax(c);

如果我将getMax的参数更改为'基于那个'?

,两个类都会满足这个原则吗?

1 个答案:

答案 0 :(得分:2)

Liskov替代原则规定,在扩展类型时,其要求应与基础相同或更宽松,而其承诺应相同或更严格。类型的方法是我们有兴趣在这里检查的主要方法。

我们不关心基类中不存在的方法,除非它们破坏了类的现有承诺,例如在没有的情况下引入可变性。这种方法不会做那样的事情,所以它无关紧要:

public Extended getMax(Extended that){
    return new Extended(Math.max(getValue(), that.getValue()));
}

我们非常关心您覆盖的方法。那么,让我们来看看你的那个:

public Base divide(Base that) {
    return new Base(getValue() / that.getValue());
}

@Override
public Extended divide(Base that) {
    return new Extended(getValue() / that.getValue());
}
  • 基本方法的要求是传递有效的Base实例,并且其getValue()不返回0.
  • 覆盖方法的要求是传递有效的Base实例,并且其getValue()不返回0.
  • 基本方法的承诺是返回有效的Base实例。
  • 覆盖方法的承诺是返回有效的Base实例,并且该实例恰好是Extended实例。

所以你用这些课来表彰Liskov替代原则。

您的代码段无法编译的原因与LSP无关:

Base b = new Base(3);
Extended c = new Extended(4);
Extended d = c.getMax(b); //doesn't work
Extended e = c.getMax(c);

只有一个getMax方法,它专门用于Extended个实例。然而,您正在将Base实例传递给它。