OO设计面试

use*_*746 0 oop design-patterns

我正在阅读史蒂夫的"5个必不可少的电话屏幕问题",同时准备下周接受采访,我遇到了这个摘录:

例如,您可能会发现一个候选人决定一个Vehicle类应该是ParkingGarage的子类,因为车库包含汽车.这只是被破坏了,并且在任何合理的训练时间内都无法修复.

由于对OO设计缺乏经验,我试图理解为什么这是一个破碎的假设?

dca*_*tro 5

加入Evan的回答:

谈到继承,尊重"是一种"(或"是一种")关系并不是整个故事.

一个好的设计也将考虑LSP(Liskov替代原则).该原则指出,如果B是A的子类型,那么A可以用B替换而没有任何令人惊讶的效果.例如,任何与a一起使用的代码Vehicle也适用于Car.

显示破坏这一原则是多么容易的经典例子是Square-Rectangle示例.

乍一看,使Square继承自Rectangle似乎相当明显.正方形"是一种"矩形.它是一个矩形,其宽度和高度始终是相同的值.为了保留这个属性,你可能会像这样设计你的Square类:

public class Square : Rectangle
{    
  //SetWidth method inherited from Rectangle
  public override void SetWidth(int width) {
    base.width = width;
    base.height = width;
  }
}
Run Code Online (Sandbox Code Playgroud)

完善.但现在,请查看以下代码:

public void SomeMethod(Rectangle rect) {
  rect.SetHeight(10);
  rect.SetWidth(20);
  print(rect.GetHeight());
}
Run Code Online (Sandbox Code Playgroud)

这段代码期望第三行打印10,因为它只是将矩形的高度设置为10.但是,如果用Square替换,它将打印20而不是导致意外行为 - 并打破Liskov替换原则.所以我们看到矩形不能总是用方块代替.

LSP是五个SOLID原则之一 - 我建议阅读更多有关其他4的原则.

如果你正在寻找一本好的OO书,我必须说Head First Design Patterns是一本书,这是我读过的最好的书.它与java略有关系,但只是略有不同,它们将它用于代码示例,而不是别的.它应该是与语言无关的,无论您的编程背景如何,您都可以阅读它.