用不同的方式解释同一个事情,会理解的更深刻。
文章目录
注1: 本文中,所有 supertype 或者 superclass 都翻译为「父类」,有人也将此翻译为「超类」或「超类型」。
父类的父类,仍然翻译为 父类,区别是直接父类和间接父类。如果在表述上有歧义,会加上说明。一般情况下,按照上下文来理解。
注2: 本文中不对 supertype(subtype) 和 superclass(subclass) 进行区分。关于这两者的区别,参考 《subtype,supertype 与 subclass,superclass 的异同》
LSP 适用于面向对象编程语言,不只是 C++ 和 Java, LSP 提出的时候,Java 还没有诞生。LSP 最早的表述,也并不针对某一个特定的 OOP 语言,是对 OOP 语言特性更抽象、更通用的表述。
表述 1:1987 ~ 1988 年,来自 Barbara Liskov
时间: 1987 年 10 月 发表在 OOPSLA 大会
1988 年 5 月 发表在 ACM SIGPLAN Notices 月刊
出处: 《Data abstraction and hierarchy 论文》
论文作者: Barbara Liskov
下载地址: 《Data Abstraction and Hierarchy》论文的 下载地址1,下载地址2,下载地址3 。
表述: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T.
翻译: 如果对于 S S S 类型的每个对象 o 1 o_1 o1,都有一个 T T T 类型的对象 o 2 o_2 o2,使得对于根据 T T T 定义的所有程序 P P P,当 o 1 o_1 o1 替换 o 2 o_2 o2 时, P P P 的行为保持不变,则 S S S 是 T T T 的子类型。
原文截图:
参考:
- Keynote address - data abstraction and hierarchy (OOPSLA 1987)
- Keynote address - data abstraction and hierarchy (ACM SIGPLAN Notices May 1988)
表述 2:1994 年,来自 Barbara Liskov
时间: 1994 年 11 月
出处: 《A Behavioral Notion of Subtyping》
论文作者:BARBARA H. LISKOV 和 JEAN NETTE M. WING
下载地址: 《A Behavioral Notion of Subtyping》论文的 下载地址1 , 下载地址2
表述: the objects of the subtype ought to behave the same as those of the supertype as far as anyone or any program using supertype objects can tell.
An assignment
x
:
T
:
=
E
x: T:=E
x:T:=E
is legal provided the type of expression E is a subtype of the declared type T of variable x.
Once the assignment has occurred, x will be used according to its “apparent” type T,
with the expectation that if the program performs correctly when the actual type of x’s object is T,
it will also work correctly if the actual type of the object denoted by x is a subtype of T.
翻译: 任何使用父类对象的程序,(在用子类对象作为父类对象时)子类的对象应该与父类对象的行为一样。
例如,赋值语句
x
:
T
:
=
E
x: T:=E
x:T:=E,
x
x
x 是变量(对象),
x
x
x 的类型是
T
T
T,
E
E
E 是表达式,
表达式
E
E
E 的值是
T
T
T 的子类时,表达式
x
:
T
:
=
E
x: T:=E
x:T:=E 是合法的。
x
x
x 会被当做
T
T
T 类对象来使用。
如果
x
x
x 对象的实际类型是
T
T
T 时,程序可以正确执行;那么,如果
x
x
x 对象的实际类型是
T
T
T 的子类时,程序也可以正确执行。
原文截图:
参考: A behavioral notion of subtyping
表述 3:1996 年,来自 Robert Martin (Bob 大叔)
时间: 1996 年
出处: Bob 大叔(Robert Martin)写的文章《The Liskov Substitution Principle》
下载地址: 《The Liskov Substitution Principle》的 下载地址1,下载地址2,下载地址3
表述: FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.
翻译: 使用指向基类的指针(或引用)的函数,必须能够使用派生类的对象,而不用对派生类有所了解。
子类的对象传给函数的时候,函数不需要了解子类的细节。
(注1:Bob 大叔对 LSP 的解读,是从 C++ 语言出发的,这样对于 C++ 开发者更容易理解,所以 LSP 的表述中出现了「函数」、「指针」。
Bob 大叔 1996 年写《The Liskov Substitution Principle》,Java 语言(1995 年)刚诞生一年。)
(注2:不知道是不是 Bob 大叔第一次把 Liskov 加到了 Substitution Principle 的前面,对于 Liskov 本人来说,即使提出「替换原则」10 多年了,在 2000 年自己的书中,也不会说这是「The Liskov Substitution Principle」,而只说「Substitution Principle」,到 2009 年的 《The Power of Abstraction》讲义 第 50 页,Barbara Liskov 教授使用了「The Liskov Substitution Principle」。)
原文截图:
参考:
The Liskov Substitution Principle
表述 4:2000 年,来自 Barbara Liskov
时间: 2000 年 5 月
出处: 《Program Development in Java: Abstraction, Specification, and Object-Oriented Design》一书
作者 Barbara Liskov 和 John Guttag
下载地址: www.pdfdrive.com 上有电子版,自行搜索
表述: In particular, supertype’s behavior must be supported by the subtypes: subtype objects can be substituted for supertype objects without affecting the behavior of the using code.
For example, code can be written in terms of the Reader
type, yet work correctly when using a BufferedReader
.
翻译: 父类型的行为必须被子类型支持:子类型的对象可以替换掉父类型的对象,而不会影响到代码的行为。例如,用 Reader
类写的代码,在使用 BufferedReader
的对象时,仍然能够正确运行。
(注:书名「Program Development in Java」,Barbara Liskov 将「替换原则」用到了 Java 语言上。)
原文截图:
参考:
Program Development in Java: Abstraction, Specification, and Object-Oriented Design (www.amazon.com)
表述 5:2002 年,来自 Bob 大叔
时间: 2002 年 10 月 15 日 (书的第一版出版时间)
出处: 《Agile Software Development, Principles, Patterns, and Practices》一书
作者:Robert C Martin
下载地址: www.pdfdrive.com 上有电子版,自行搜索
表述: SUBTYPES MUST BE SUBSTITUTABLE FOR THEIR BASE TYPES.
翻译: 子类型必须可以替换掉他们的基类型。
(在实际编码中,子类型的对象可以作为父类对象来使用)
原文截图:
参考:
Agile Software Development, Principles, Patterns, and Practices (on Amazon.com)
表述 6:2009 年,来自 Barbara Liskov
时间: 2009 年 11 月
出处: 《The Power of Abstraction》讲义
作者:Barbara Liskov
下载地址: 《The Power of Abstraction》讲义的 下载地址
表述: Objects of subtypes should behave like those of supertypes if used via supertype methods
翻译: 子类型的对象,如果通过父类型的方式使用,应该和父类型的对象的行为一致。
(类似于这样: 父类 obj = 子类对象
)
原文截图:
参考:
Barbara Liskov 主页: https://pmg.csail.mit.edu/~liskov/
主页中的 Power of Abstraction Slides [ ppt | pdf ]
表述 7:2016 年,来自 THEODORE S. NORVELL
时间: 2016 年 3 月 11 日
出处: THEODORE S. NORVELL 的课程讲义 《Software Design (Engi-5895) 2016》,更新于 2016 年 3 月 11 日,讲义最早是2007 年写的。
下载地址: 《Software Design (Engi-5895) 2016》中,关于 LSP 的 讲义:Agile Design Principles: The Liskov Substitution Principle (pdf)
表述: If S is a declared subtype of T, objects of type S should behave as objects of type T are expected to behave, if they are treated as objects of type T
Note that the LSP is all about expected behaviour of objects. One can only follow the LSP if one is clear about what the expected behaviour of objects is.
翻译: 如果 S 是 T 的子类型,当 S 类型的对象被当做 T 类型的对象时,S 类型的对象的行为应该和 T 类型的对象的行为一致。
LSP 完全是关于对象的预期行为,只有清晰地知道对象的预期行为是什么,才能做到遵循 LSP。
关于 If S is a declared subtype of T,作者的解释是这样的:
对 Java 来说,满足以下条件之一,S 是 T 的声明子类型:
- S 就是 T
- S implements T,或者 S extends T
- S implements 或者 extends 某个类,这个类 implements 或者 extends T,以此类推。
原文截图:
参考:
- https://www.engr.mun.ca/~theo/Courses/sd/notes.html
The Liskov Substitution Principle (LSP)[Updated Mar 11.] - https://www.engr.mun.ca/~theo/Contact/index.html