跳到主要内容

鸭子类型 vs 原型链:两种世界观

前面我们学了类和继承,一切看起来很和谐。但当你深入思考"一个对象到底是什么类型"这个问题时,Python 和 JS 会给出截然不同的答案。

鸭子类型:"你能嘎嘎叫,你就是鸭子"

Python 信奉一句名言:

"If it walks like a duck and quacks like a duck, then it must be a duck." (如果它走路像鸭子、叫起来像鸭子,那它就是鸭子。)

翻译成编程语言:我不关心你是什么类型,我只关心你能做什么。

加载代码编辑器中……

注意:Python 版本的 duck_test 根本没有类型检查——只要你有 quack()walk() 方法就行,管你是鸭子还是人。这就是"鸭子类型"。

JS 其实也支持这种风格(因为它也是动态类型),但 JS 社区更倾向于检查 typeof 来防御。

原型链:JS 的"家谱"

JS 的每个对象都有一个隐藏的链条——原型链(prototype chain)。当你访问一个属性时,JS 会沿着这条链往上找:

加载代码编辑器中……

两种语言都有"往上找"的机制:Python 叫 MRO(Method Resolution Order),JS 叫 原型链(Prototype Chain)。但底层实现完全不同——Python 用的是 C3 线性化算法,JS 是简单的链表。

isinstance vs instanceof

有时候你还是需要检查类型:

加载代码编辑器中……
PythonJavaScript
继承链检查isinstance(obj, Class)obj instanceof Class
精确类型type(obj) == Classobj.constructor === Class
基本类型type(x)typeof x
多类型检查isinstance(x, (int, str))需要手动 ||

Python 的协议 vs JS 的接口(概念对比)

Python 有一个强大的概念叫协议(Protocol)——你不需要继承任何东西,只要实现了特定方法,就能被当作特定类型使用:

加载代码编辑器中……
能力Python 实现JS 实现
可获取长度__len__get length()
可迭代__getitem____iter__[Symbol.iterator]()
可包含检查__contains__手动实现 includes()
可比较__eq__, __lt__无直接等价

Python 的协议系统是鸭子类型的高级形式:只要你实现了 __len__len() 就能用;实现了 __getitem__for 循环就能用。不需要继承任何基类,不需要声明任何接口。JS 的 Symbol.iterator 是类似思路,但覆盖面远不如 Python 的 dunder 方法广。

什么时候不该用 OOP?

OOP 不是万能药。以下场景你可能不需要类:

加载代码编辑器中……

经验法则:

  • 有状态 + 有行为 -> 用类
  • 只有数据 -> 用字典/对象或 dataclass
  • 只有行为 -> 用普通函数
  • 需要多个实例、每个有不同状态 -> 用类
问问 AI

问 AI:"什么是组合优于继承(Composition over Inheritance)?能给我一个例子说明什么时候用组合比用继承更好?"

经典例子:一个 FlyingFish(飞鱼)是鱼还是鸟?如果用继承,你得选一个。如果用组合,你可以给鱼"装上"飞行能力,就像给手机装个保护壳一样灵活。

🏋️AI 练习

创建一个"可排序的学生列表":

  1. Student 类:属性 namescore
  2. 在 Python 中,实现 __lt__(小于比较)和 __str__,使得 sorted() 可以直接排序学生列表
  3. 在 JS 中,实现 toString(),并用 sort() 配合自定义比较函数排序

创建 5 个学生,按成绩从高到低排序并输出。体会 Python 协议系统的优雅之处。

小结

概念PythonJavaScript
类型哲学鸭子类型(看行为)原型链(看血统)
类型检查isinstance()instanceof
精确类型type()typeof / .constructor
协议/接口dunder 方法(__len__ 等)Symbol.*
迭代协议__iter__ / __getitem__Symbol.iterator

一句话:Python 不在乎你是谁,只在乎你能干啥(鸭子类型)。JS 看你的原型链家谱来判断你的身份。 两种方式各有优劣——鸭子类型灵活但可能出意外,原型链明确但不够灵活。理解这个差异,你就真正理解了两种语言的 OOP 哲学。