java - 对象 toString 方法和 Liskov 替换原理
问题描述
每个类都直接或间接地从该类继承Object
。
除其他外,该类Object
具有重要的方法,通常被覆盖:toString
.
问题是:这种方法的覆盖是否会导致对Object
类的 Liskov 替换原则的违反?
我举个例子。
public class Main
{
public static void main(String[] args)
{
Object o = new Object();
String s = o.toString();
if (s.indexOf('@') > -1) {
System.out.println("OK");
} else {
System.out.println(":-(");
}
}
}
public class MyClass
{
private int x;
public string toString()
{
return Integer.toString(x);
}
}
显然,如果我替换new Object()
为new MyClass()
系统的行为更改。
解决方案
嗯,这是一个品味问题。Object
几乎没有保证的属性。所以也没有什么可违反的。
如果你说返回类名是这样一个可能被违反的属性,那么子类当然不应该改变这一点。但是阅读 Object.toString() 的文档发现没有这样的保证:
返回对象的字符串表示形式。通常,toString 方法返回一个“以文本方式表示”该对象的字符串。
所以我在这里没有看到 LSP 违规。
LSP 并没有说子类的行为必须与超类完全相同。这将使子类完全无用。它只要求子类满足超类的规范。
唯一可以提到的是对每个对象Object
强制执行一种无意义的方法 。更复杂的设计可能会将其放入界面中。toString
我认为这种设计选择只是一种妥协,它也被 .NET 等其他语言所取代。
推荐阅读
- sql - SQL,如何根据字段值对行进行分组
- amazon-web-services - 如何将 AWS 机密从 Terraform 获取到运行 Python 的 docker 容器中?
- vhdl - 在 VHDL 中使用 Others 和 Aggregate
- mysql - MySQL 插入 ENUM 字段留空
- kubernetes - 为什么不能更改节点池_name_?
- javascript - 您好,我的 xs 屏幕范围的菜单按钮始终存在并且无法正常工作,我很确定问题出在我的 JS 文件上
- sql - SQL左反半连接等效查询
- spring - 将 Apache Commons Lang3 添加到我的 Spring Boot 项目中
- c - MSVC 手动链接标准库
- r - 如何在R中的pairs.panels()中按组按不同颜色分隔散点图