nit*_*.kk 4 oop liskov-substitution-principle solid-principles
我在学习liskov substitution principle。它说sub classes should be proper replacement for the base classes。
我读了一个例子,我在互联网的不同地方找到了这个例子。一类Rectangle.java与height, width他们setter and getter methods。一个Square.java只需要一个属性的类,即length. 如果我们有,Square.java extending Rectangle.java那么这违反了这一原则。这是因为Rectangle.java期望的用户width只要height修改就不会受到影响,反之亦然。
我的疑惑:
我们看到的情况是,方法只是用空的打开和关闭大括号覆盖,以防止执行在基类中编写的默认代码。这种情况是否违反了这一原则?
这个原则也说不inheritance应该仅仅用于重用代码。在下面的情况下,这是一种不好的做法,这是否违反了这一原则?
如果类 Window.java 可从某个图形库获得。假设它具有绘制窗口所需的所有代码。还假设它在使用和绘制时有一个工具栏。如果要求是创建一个没有工具栏的窗口。
简单地创建一个 WindowWithoutToolBar.java 扩展 Window.java 并覆盖 drawToolBarMethod() 并将其留空就可以解决目的。 [可能只是创建工具栏而不是绘制它,以避免其他方法尝试访问工具栏时发生任何异常object] 这是一种不好的做法吗?
创建一个没有工具栏的全新 Window 类将需要重写所有已经在 Window.java 中编写的代码。
现在如果我们需要 AbsoluteNumber.java 那么如果我们从 Integer.java 扩展它,这是否违反了这个原则(如果 Integer.java 有一些方法如 getValueAfterMultiplyByNegativeOne())?
请提供您的宝贵意见。
问候,
克里希纳·库马尔
有一个检查清单来确定您是否违反了 Liskov。
检查清单:
历史约束:当覆盖一个方法时,你不能修改基类中不可修改的属性。看看这些代码,你可以看到 Name 被定义为不可修改(私有集),但 SubType 引入了允许修改它的新方法(通过反射):
public class SuperType
{
public string Name { get; private set; }
public SuperType(string name, int age)
{
Name = name;
Age = age;
}
}
public class SubType : SuperType
{
public void ChangeName(string newName)
{
var propertyType = base.GetType().GetProperty("Name").SetValue(this, newName);
}
}
Run Code Online (Sandbox Code Playgroud)还有另外两个项目:方法参数的逆变和返回类型的协方差。但是在 C# 中是不可能的(我是 C# 开发人员)所以我不关心它们。
参考: