在之前的代码中就有两个这样的例子:drive() 被定义在 Vehicle 和 Car 中 , ignition() 被定义在 Vehicle 和 SpeedBoat 中 。
我们可以在 ignition 中看到多态非常有趣的一点 。 在 pilot 中通过相对多态引用了 Vehicle 中的 drive 。 但是那个 drive 方法直接通过名字引用了 ignition 方法 。
作者在这里介绍的是传统语言中的多态 。 这里讲了太多的例子 , 看起来有些混乱 。
那么语言引擎会使用哪个 ignition 呢?Vehicle 还是 SpeedBoat 的?实际上它会使用 SpeedBoat 的 ignition 。 如果你直接实例化了 Vehicle 类然后调用它的 drive , 那语言引擎就会使用 Vehicle 中的 ignition 方法 。
换言之 , ignition 方法中的定义的多态性取决于你是在哪个类的实例中引用它 。
这似乎是一个过于深入的学术细节 , 但是只有深入了解这个细节才能理解 JavaScript 中的类似的 [[Prototype
机制 。
在子类中也可以相对引用它继承的父类 , 这种相对引用通常被称为 super 。
从概念上来说 , 子类 Bar 应当可以通过相对多态引用(或者说 super)来访问父类 Foo 中的行为 。 需要注意的是 , 子类得到的仅仅是继承自父类行为的一个副本 。 子类对继承到的一个方法进行重写 , 不会影响到父类的方法 , 这两个方法之间互不影响 , 因此才能使用相对多态访问父类中的方法 。
多态并不表示子类和父类有关联 , 子类得到的只是父类的一个副本 , 类的继承其实就是复制 。
多重继承还记得我们之前关于父类、子类的 DNA 讨论吗?当时我们说这个比喻不太恰当 , 因为现实中绝大多数是由双亲生的 。 如果类可以继承两个类 , 那看起来就更符合现实了 。
作者在这里对多态进行了案例的介绍 , 观点只有一个:类的继承其实就是复制 , 子类是一个副本 。
有些面向对象的类允许你继承多个「父类」 。 多重继承意味着所有的父类的定义都会被复制到子类中 。
从表面来看 , 对于类来说这似乎是一个非常有用的功能 , 可以把多个功能组合到一起 , 然而 , 这个机制同时也会带来复杂的问题 。 如果两个父类都定义了 drive 方法的话 , 那么子类引用的是哪一个呢?难道每次都需要手动指定具体父类的 drive 方法吗?
除此之外 , 还有一种被称为钻石问题的变种 。 在钻石问题中 , 子类 D 继承两个父类 B 和 C , 这两个父类都继承自 A 。 如果 A 中有 drive 方法 , 并且 B 和 C 都重写了这个方法的 , 那么 D 引用 drive 时应该选择哪个版本呢?
这些问题远比看上去复杂得多 , 之所以要介绍这些问题 , 主要是为了和 JavaScript 的机制进行对比 。
相比之下 , JavaScript 要简单的多:它本身并不提供「多重继承」功能 。 许多人认为这是件好事 , 因为使用多重继承的代价太高 。 然而这无法阻挡开发者们的热情 , 他们会尝试各种办法来实现多重继承 。
混入在继承或者实例化时 , JavaScript 的对象机制并不会自动执行复制行为 。 简单来说 , JavaScript 中只有对象 , 并不存在可以被实例化的「类」 。 一个对象并不会被复制到其他对象 , 它们会关联起来 。
由于在其他语言中类表现出来的都是复制行为 , 因此 JavaScript 开发者想出一个方法来模拟类的复制行为 , 这个方法就是混入 。 接下来我们会看到两种类型的混入:显式和隐式 。
- javascript|穿戴设备将迎变革,OPPO又增新专利,能提升模式切换效率!
- 6月24日|首款华为鸿蒙OS燃油车 北汽魔方预售:10.29万起
- 数字化转型|2000元内有10.3英寸电子墨水屏产品吗?这款售1999元,配置有特色
- 特斯拉|北京魔方正式开启预售!搭载华为鸿蒙OS系统,预售价10.29万起
- 红杉资本|广州蓝景技术分享—开发语言JavaScript之多线程
- 电子商务|疑似华为新款平板获3C认证或7月发布40W快充+10.8英寸屏+鸿蒙OS
- Word工具箱10.20 下载安装教程(免费版)
- 电子商务服务业|1—5月信息传输业基础设施投资增长10.6%
- Java|华为matepad 10.8寸新品入网?支持40瓦的快充
- javascript|避雷指南:线上免费申请的流量,这些问题你关注了吗
