从java的角度看typescript的subtyping与inheritance的区别
Author:zhoulujun Date:
之前我觉得对subtyping与inheritance理解的差不多了,但是看了知乎推荐的这个回答
subtyping和inheritance的区别是什么? - Sayako Hoshimiya的回答 - 知乎
https://www.zhihu.com/question/57486254/answer/153071178
然后还是觉得深究一下。其实google一下,找到的细说这个两个概念的中文文章还是比较少的
我比较认可的回答是:
我的看法是,这俩是不同领域的术语,没必要硬扯到一起,在具体场景下可能相关也可能不相关。
比如像 Java/C++ 之类的基于 class 的面象对象语言,inheritance 必然也定义了一个子类型;
而象 ES6 之前的 JavaScript,基于属性拷贝(如_.extend())的 inheritance 是直接在对象实例之间完成的,并不涉及类型定义,而基于原型链的(包括 ES6 的 class)就可以视为 subtyping 了
链接:https://www.zhihu.com/question/57486254/answer/15308022
对比java与typescript来讲,这个是一贯风格
Subtyping in TypeScript
先看这篇:Subtyping in TypeScript https://juejin.cn/post/6959498972268822542
再看这篇: 理解TypeScript中“类型”的概念到底有多难? https://www.tangshuang.net/8140.html
子类型是一个庞大的话题,涉及到抽象概念、(推导)规则、协变、逆变等等,你可以阅读这篇文章深入了解,本文只会聊其中很小的一部分。子类型揭示了TS类型系统的核心实质,它是一个推导系统,推导即基于某些定理、公理、定律进行演算的过程(在TS中主要是基于内建的一些规则用于检查值的类型)。
TS的类型基于“集合”的概念
一个类型,代表一个集合。例如string类型代表的是所有字符串的集合。
在检查过程中,如何决定一个值属于这个“集合”呢?它的依据在于这个值的“形状(Shape)”。
怎么定义值的形状呢?
它由两部分组成,一部分是基于JS的基础类型,得到该值的数据类型,另一部分是基于TS的另外一个核心Structural(结构化的),得到该值的结构。基于数据类型和结构这两个概念,TS获得值的形状,基于“推导”的运行方式,决定该值是否符合某个类型。
正是这样,那么下面两个类型,在TS里面,竟然是“相等”的(仅类型相等,A === B为false):
class A { name: string; } class B { name: string; }
在Java或C#这样的语言中,完全不能被理解,它俩怎么可能相等?而在TS中,它们代表着形状为 { name: string } 的对象(JS中一切复合类型皆是对象)的集合。
一个值,在TS中,它和集合的对应关系不是一对一的,它可以同时属于多个集合中,是一对多的关系。而同时,两个不同的集合,却可能表达相同的形状。如果你看它像鸭子,那么它就是鸭子。于是,A和B相等了,只是取了不同的名字而已,就像一个人在这个杂志上叫鲁迅,在另一个杂志上叫润土。
TS是怎么对待(treat)这些集合的呢?它基于一种推导的范式确定两个集合之间的关系。两个集合存在什么关系呢?只存在两种关系:
一种是A是B的子类型,另一种是A不是B的子类型。(A和B可交换位置)子类型,是TS对待类型集合的唯一方式。在TS中,所有类型的总和,都处在子类型体系中,这个子类型体系是一个树状网络,它的根是一个叫unknow的类型,而它的底是一个叫never的类型(never是所有类型的子类型,是树状的所有叶子)。
子类型用于表达类型与类型的二元关系,当一个值的类型属于某一类型时,它同时属于该类型的父类型。它的产生方式又有多种,
基于父类型扩展,也就是使用extends
基于一种叫交叉(A & B)的操作得到
基于一种叫联合(A | B)的操作得到
曾经有这样一个预言,让一只猴子坐在一台电脑前敲击键盘,总有一天它能敲出莎士比亚的所有著作(猴子不懂艺术)。同样的道理,只要给定条件,你永远可以在TS的子类型体系中找到对应的类型,而这个过程基于“推导”完成。因此,实际上,子类型的产生方式只有一种而非三种或更多,这种方式就是基于某一类型(never除外)扩展出新类型。
参考文章:
转载本站文章《从java的角度看typescript的subtyping与inheritance的区别》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/typescript/2021_0831_8672.html