里氏替换原则的翻译问题,o1 is substituted for o2 到底是谁替换谁

1. Liskov Substitution Principle (LSP)

本文讨论的「里氏替换原则」是 Barbara Liskov 最早提出的「替换原则」的版本:

If for each object o 1 o_1 o1 of type S S S there is an object o 2 o_2 o2 of type T T T such that for all programs P P P defined in terms of T T T, the behavior of P P P is unchanged when o 1 o_1 o1 is substituted for o 2 o_2 o2, then S S S is a subtype of T T T.

关于 LSP 的这种表述,很多人都觉得这段描述有些晦涩难懂,其中,包括不少写了设计模式书籍的写作者。

当然,很可能他们是谦虚,为了说这段难懂,然后引出一个更简单的描述:
Objects of subtypes should behave like those of supertypes if used via supertype methods
或者
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
前面那句,源自 Barbara Liskov,后面这句,源自 Robert Martin (Bob 大叔)。

其实,利用我们学过的英语,足以看懂那段看似难懂的描述。
先解决两个点:
(1) in terms ofall programs P P P defined in terms of T T T ,是指 用 T 编写了程序 P。

(2)is substituted for: when o 1 o_1 o1 is substituted for o 2 o_2 o2,到底是谁替换谁? 是用 o 1 o_1 o1 替换掉 o 2 o_2 o2

搞清楚这两点,再来看:
If for each object o 1 o_1 o1 of type S S S there is an object o 2 o_2 o2 of type T T T such that for all programs P P P defined in terms of T T T, the behavior of P P P is unchanged when o 1 o_1 o1 is substituted for o 2 o_2 o2, then S S S is a subtype of T T T.

已知: T T T 写的程序 P P P S S S 的对象 o 1 o_1 o1 T T T 的对象 o 2 o_2 o2
动作: o 1 o_1 o1 替换掉 o 2 o_2 o2 (用 S S S 的对象替换 T T T 的对象)
期望: P P P 的行为不变 (意味着有可能达不到期望)
结论: S S S T T T 的子类

隐含的结论是,如果 P P P 的行为改变了,那么 S S S 可能不是 T T T 的子类 , 或者说, S S S 类作为 T T T 的子类,实现的并不好。

反过来说,当 S S S T T T 的子类时(通常我们通过 继承 来保证的),用 S S S 的对象替换 T T T 的对象, P P P 的行为应该保持不变。
这里说「应该」,是因为并不是每一次这样的替换, P P P 的行为都不变。如果 P P P 的行为变了,叫做「违背 里氏替换原则」,这是需要避免的。
关于「什么是行为不变」,将会另写一篇博文来介绍。

关于 LSP 的表述,可以参考: 【LSP简史】里氏替换原则的 7 种表述方式

2. A is substituted for/by/with B

2.1 A is substituted for B,是用 A 替换 B

或者说,把 B 替换为 A

所以,when o 1 o_1 o1 is substituted for o 2 o_2 o2 的意思是,用 o 1 o_1 o1 替换 o 2 o_2 o2,或者 把 o 2 o_2 o2 替换成 o 1 o_1 o1 o 1 o_1 o1 替换掉 o 2 o_2 o2, 把 o 2 o_2 o2 替换为 o 1 o_1 o1

不能说成, o 1 o_1 o1 替换为 o 2 o_2 o2,把 o 1 o_1 o1 替换成 o 2 o_2 o2

2.2 对比:is substituted for 和 is substituted by/with

A is substituted for B,是用 A 替换 B。 前者替换后者。
substitute A for B ,A 替换 B, 前者替换后者。

A is substituted by B,是 A 被替换为 B,即,用 B 替换 A。 后者替换前者。
A is substituted with B 与 A is substituted by B 的意思一样。后者替换前者。
substitute A with/by B, B 替换 A。后者替换前者。

小结:
substitute + for:用 前者 替换 后者,实际使用的是 前者。
substitute + with/by 用 后者 替换 前者,实际使用的是 后者。
与 substitute 的主动、被动语态无关。

3. 百度翻译 vs. 必应翻译,谁翻译的对?

3.1 百度翻译

翻译的结果: 如果对于类型为 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 的子类型。

在这里插入图片描述

3.2 必应翻译

翻译的结果: 如果对于 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 的子类型。

在这里插入图片描述

4. 参考

https://www.usingenglish.com/forum/threads/substituted-by-substituted-fo-substitution-of-for.98412/

  • substitute + for
    (1) substitute A for B – this means A takes the place of B – use A
    (2) substitute B for A – B takes the place of A – use B
    (3) B was substituted for A – B takes the place of A – use B
    (4) A was substituted for B – A takes the place of B – use A

  • substitute + with/by
    (1) substitute A with/by B – B takes the place of A – use B
    (2) substitute B with/by A – A takes the place of B – use A
    (3) A was substituted with/by B – B takes the place of A – use B
    (4) B was substituted with/by A – A takes the place of B – use A

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的 Java 程序,用于对 26 个英文字母进行相互替换: ```java import java.util.HashMap; import java.util.Map; public class LetterSubstitution { private static final Map<Character, Character> substitutionMap = new HashMap<>(); static { substitutionMap.put('a', 'z'); substitutionMap.put('b', 'y'); substitutionMap.put('c', 'x'); substitutionMap.put('d', 'w'); substitutionMap.put('e', 'v'); substitutionMap.put('f', 'u'); substitutionMap.put('g', 't'); substitutionMap.put('h', 's'); substitutionMap.put('i', 'r'); substitutionMap.put('j', 'q'); substitutionMap.put('k', 'p'); substitutionMap.put('l', 'o'); substitutionMap.put('m', 'n'); substitutionMap.put('n', 'm'); substitutionMap.put('o', 'l'); substitutionMap.put('p', 'k'); substitutionMap.put('q', 'j'); substitutionMap.put('r', 'i'); substitutionMap.put('s', 'h'); substitutionMap.put('t', 'g'); substitutionMap.put('u', 'f'); substitutionMap.put('v', 'e'); substitutionMap.put('w', 'd'); substitutionMap.put('x', 'c'); substitutionMap.put('y', 'b'); substitutionMap.put('z', 'a'); } public static String substitute(String text) { StringBuilder sb = new StringBuilder(); for (char c : text.toCharArray()) { if (Character.isLetter(c)) { char substituted = substitutionMap.get(Character.toLowerCase(c)); sb.append(Character.isLowerCase(c) ? substituted : Character.toUpperCase(substituted)); } else { sb.append(c); } } return sb.toString(); } public static void main(String[] args) { String text = "Hello, world!"; String substitutedText = substitute(text); System.out.println(substitutedText); // "Svool, dliow!" } } ``` 该程序使用了一个 HashMap 来存储每个字母的替换结果,然后遍历输入的字符串,对每个字母进行替换。如果需要替换的字母是大写字母,则替换后的字母也是大写字母;如果需要替换的字母是小写字母,则替换后的字母也是小写字母。最后将替换后的字符串返回。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值