Subtyping for OOP.
在 Java 与 C# 这些 statically typed OOP 语言中存在许多容易混淆的概念,如 inheritance v.s. subtyping, class v.s. type 等,这一节将对其进行澄清。(很重要的一节!)
在之前,我们使用 ML-like MUPL 中的 record feature 来解释了 subtyping。其实对于 OOP 中的 object,我们也可以视为一个 record:An object is basically a record holding fields (which we assume here are mutable) and methods (we assume the “slots” for methods are immutable).
结合之前我们基于 record 与 higher-order function 研究的 width typing 与 function typing,我们定义 OOP 中的 subtyping 规则如下:
- (Width typing for fields) A subtype can have extra fields.
- (NO depth typing for fields) Because fields are mutable, a subtype cannot have a different type for a field.
- (Width typing for methods) A subtype can have extra methods.
- (Depth typing for methods) Because methods are immutable, a subtype can have a subtype for method, which means the method in the subtype can have contravariant argument types and a covariant result type.
虽然我们可以将 object 视为 PL 中的 record,Java 与 C# 中的 object types 与 ML-like 的 record types,function types 却有着很大的不同。
In Java and C#, we reuse class (interfaces) names as types. If there is a class Foo, then the type Foo includes in it all fields and methods inplied by the class definition (including superclasses).
Subtyping in Java and C# includes only the subtyping explicitly stated via:
- the subclass relationship.
- the interfaces that classes explicitly indicate they implement (including interfaces implemented by superclasses).
接下来我们介绍 OOP 中的 subclassing 规则:它比 subtyping 规则更为严格,因此可以 soundly 地阻止 field missing 与 method missing 错误。
- A subclass can add fields but not remove them.
- A subclass can add methods but not removed them.
- A subclass can override a method with a covariant return type. (在 C++ 中,这条规则更为严格,重写方法地参数表与返回值地类型均不能改变)
- A class can implement more methods than an interface requires or implement a required method with a covariant return type.
注意,classes 与 types 是两个完全不同的概念!!!
在 C# 与 Java 这种语言中,每个 class declaration 在定义 class 的同时引入同名的 type。为了方便, classes 与 types 的界限被刻意模糊了。类似的,inheritance (subclassing) 与 subtyping 的界限也变得很暧昧。
但实际上这些概念是有本质上的区别的。(高能预警,接下来的内容很精华,就不翻译了)
A class defines an object’s behavior. Subclassing inherits behavior, modifying behavior via extension and override.
A type describes what fields an object has and what messages it can respond to. Subtyping is a question of substitutability and what we want to flag as a type error.