博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
trait,线性化
阅读量:6360 次
发布时间:2019-06-23

本文共 868 字,大约阅读时间需要 2 分钟。

hot3.png

近来重新拾起scala,看到trait,要总结一下,因为这玩意的逻辑不是那么明显,很容易就忘了

下文出现的“父子关系”指的是可能跨越多代的继承关系

首先要理解线性化是怎么做的。线性化简单来说就是,写在越后面的trait的“优先级”越大。
举个例子,假设某个类Z线性化以后的结果是
A  B  C  D  E  F  Z
然后,假设有一个方法叫m1,从左到右地扫描上面的“链”,这个m1首先出现在B,那么我们知道,B的后代是可以有机会override这个m1的。
我们从B开始,继续向右扫描,寻找“和B是父子关系”并且“override了m1”的trait,假设是D和F,F的位置在D的后面,所以,当我们调用Z的m1,其实就是在调用F的m1。很有趣的事情是,当你将一个Z类型的对象转型为类型D,然后去调用m1,执行的是F的m1,但是D和F并没有父子关系,也就是说,这是一种“兄弟之间的覆写行为”,与java做对比的话,java里面的override,必然是“父子之间的覆写行为”,因为java的override只发生在类与类之间,java的继承的特点是单一继承,而scala的trait的继承,其实是多重继承那一套。
不禁要问,如果在上面的链,存在一个trait,譬如说 C,它也有一个叫m1的方法,但是它跟B没有父子关系,那会怎么样?
答案就是:编译器不会让你的代码通过!因为这是一种”意外发生的命名冲突“,而override是“继承链中意图明确的覆写”。
那要怎么解决?解决的办法就是,你要在Z里面定义一个Z自己的override def m1。为什么这样就可以了?
当你在Z里面定义了一个 override def m1 的时候,你实际上是在用Z的m1来覆写B和C里的m1。C和B的m1是不能互相覆盖的,因为它们的m1根本没有“血缘关系”,只是恰好取了同一个名字而已,但是,Z是B的后代,Z也是C的后代,所以,Z可以覆写B的方法,也可以覆写C的方法。

转载于:https://my.oschina.net/mustang/blog/159635

你可能感兴趣的文章
Eclipse Debug Android Native Application
查看>>
java动态代理
查看>>
node.js原型继承
查看>>
揭露让Linux与Windows隔阂消失的奥秘(1)
查看>>
我的友情链接
查看>>
Mysql备份和恢复策略
查看>>
linux17-邮件服务器
查看>>
AS开发JNI步骤
查看>>
二分查找,php
查看>>
python面试题-django相关
查看>>
Python——eventlet.greenthread
查看>>
记大众点评之面试经历
查看>>
第三章:基本概念
查看>>
Jersey+mybatis实现web项目第一篇
查看>>
C++形参中const char * 与 char * 的区别
查看>>
espresso 2.0.4 Apple Xcode 4.4.1 coteditor 价格
查看>>
Object-C中emoji与json的问题
查看>>
linux 命令
查看>>
灾后重建
查看>>
Nothing 和 Is
查看>>