Tag: lsp

重写getPreferredSize()会破坏LSP

我总是在这个站点中看到覆盖getPreferredSize()建议,而不是使用setPreferredSize() ,例如这些先前的线程中所示。 使用重写getPreferredSize()而不是对固定大小的组件使用setPreferredSize() 我应该避免在Java Swing中使用set(Preferred | Maximum | Minimum)Size方法吗? 重写setPreferredSize()和getPreferredSize() 看这个例子: public class MyPanel extends JPanel{ private final Dimension dim = new Dimension(500,500); @Override public Dimension getPreferredSize(){ return new Dimension(dim); } public static void main(String args[]){ JComponent component = new MyPanel(); component.setPreferredSize(new Dimension(400,400)); System.out.println(component.getPreferredSize()); } } setPreferredSize() 设置此组件的首选大小。 getPreferredSize() 如果preferredSize已设置为非null值,则返回它 。 如果UI委托的getPreferredSize方法返回非null值,则返回该值; 否则遵从组件的布局管理器。 所以这样做显然打破了Liskov替代原则 。 […]

如何避免破坏Liskov替换原则(LSP)?

我的情况与Steve Complete所提到的Steve McConnell非常相似。 只有我的问题是基于车辆和三轮车才恰好依据法律属于汽车类别。 到目前为止,汽车有四个轮子。 任何方式我的域都不必要地复杂,所以很容易坚持下面的猫示例。 怀疑覆盖例程的类并在派生例程中不执行任何操作这通常表示基类设计中的错误。 例如,假设您有一个Cat类和一个例程Scratch(),并假设您最终发现某些猫被声明并且无法划伤。 您可能想要创建一个派生自Cat的名为ScratchlessCat的类,并重写Scratch()例程以不执行任何操作。 这种方法存在几个问题: 它通过改变其接口的语义来违反Cat类中提供的抽象(接口契约)。 当您将其扩展到其他派生类时,此方法很快就会失控。 当你发现没有尾巴的猫时会发生什么? 还是一只没有抓到老鼠的猫? 还是一只不喝牛奶的猫? 最终你会得到像ScratchlessTaillessMicelessMilklessCat这样的派生类。 随着时间的推移,这种方法会导致代码难以维护,因为祖先类的接口和行为对其后代的行为意味着很少或根本没有。 解决此问题的地方不在基类中,而是在原始Cat类中。 创建一个Claws类并在Cats类中包含它。 根本问题是假设所有猫都抓了,所以在源头解决这个问题,而不是仅仅在目的地包扎它。 根据他上面的伟大着作中的文字。 以下是坏事 父类不必是抽象的 public abstract class Cat { public void scratch() { System.out.println(“I can scratch”); } } 派生类 public class ScratchlessCat extends Cat { @Override public void scratch() { // do nothing } } 现在他建议创建另一个类Claws […]