继承:站在巨人的肩膀上
什么是继承?
你爸妈把黑眼睛、黑头发"传"给了你——这就是继承。在编程中:
- 父类(基类)定义通用的属性和方法
- 子类(派生类)继承父类的一切,还能添加自己的特色
这样你就不用从零开始造轮子了。写好一个 Animal 类,Cat、Dog、Parrot 都能"白嫖"它的代码。
基本继承
加载代码编辑器中……
| Python | JavaScript | |
|---|---|---|
| 声明继承 | class Cat(Animal): | class Cat extends Animal |
| 调用父类构造 | super().__init__(...) | super(...) |
两种语言的继承语法意外地相似!Python 用括号 (Animal),JS 用关键字 extends。
方法重写(Override)
子类可以"覆盖"父类的方法,提供自己的实现:
加载代码编辑器中……
这就是多态的威力:circle.describe() 和 rect.describe() 调用的是同一个父类方法,但各自用的是自己的 area() 实现。父类方法调用 self.area() / this.area() 时,会自动找到子类重写的版本。
用 super() 扩展父类方法
有时候你不想完全替换父类方法,而是在它基础上加点料:
加载代码编辑器中……
| 场景 | Python | JavaScript |
|---|---|---|
| 构造函数中调父类 | super().__init__(...) | super(...) |
| 普通方法中调父类 | super().method(...) | super.method(...) |
注意区别:Python 的 super() 返回一个对象,你在上面调方法用 .;JS 在构造函数中直接 super(...),在其他方法中 super.method(...)。
踩坑提醒
忘记调用 super() 是继承中最常见的 bug!
- Python:忘了
super().__init__()不会报错,但父类的属性不会被初始化,后面访问时就炸了 - JS:在子类 constructor 中忘了
super()会直接报错(ReferenceError),因为this在super()调用前不可用
JS 在这点上更"安全"——它强制你调用 super(),而 Python 允许你静悄悄地搞砸一切。
Python 的多重继承 vs JS 的单继承
这是两种语言在继承上的重大区别:
加载代码编辑器中……
| Python | JavaScript | |
|---|---|---|
| 多重继承 | 原生支持 class C(A, B): | 不支持,用 Mixin 模拟 |
| 方法冲突解决 | MRO(C3 线性化算法) | 原型链(单链) |
Python 的多重继承很强大,但也容易造成"菱形继承"的混乱(当两个父类有同名方法时)。JS 干脆不提供多重继承,用 Mixin 模式来组合功能——虽然写起来麻烦一点,但不容易翻车。
初学阶段不用深究 MRO 和 Mixin。记住一点就好:Python 可以有多个爸妈,JS 只能有一个。
🏋️AI 练习
创建一个小型的"RPG 角色系统":
- 基类
Character:属性name、hp(生命值),方法attack(target)打印攻击信息 - 子类
Warrior:额外属性armor(护甲),重写attack方法加上力量描述 - 子类
Mage:额外属性mana(法力),新增cast_spell(spell_name)方法
用 Python 和 JS 各写一版。创建一个战士和一个法师,让他们互相攻击。
小结
| 概念 | Python | JavaScript |
|---|---|---|
| 声明继承 | class B(A): | class B extends A |
| 调用父类构造 | super().__init__() | super() |
| 调用父类方法 | super().method() | super.method() |
| 多重继承 | 原生支持 | 不支持(Mixin 代替) |
| 方法解析 | MRO(C3) | 原型链 |
一句话:继承让你复用代码,super 让你扩展而非替换。Python 支持多爹,JS 只认一个。