scala学习手记34 - trait方法的延迟绑定
trait的方法的延迟绑定就是先混入的trait的方法会后调用。这一点从上一节的实例中也可以看出来。
下面再来看一个类似的例子:
abstract class Writer {
def write(message: String): String
}
trait UpperWriter extends Writer {
abstract override def write(message: String): String = super.write(message.toUpperCase)
}
trait FilterWriter extends Writer {
abstract override def write(message: String): String = super.write(message.replace('o', '-'))
}
trait StringWriter extends Writer {
def write(message: String): String = message
}
val myWriter1 = new StringWriter with UpperWriter with FilterWriter
val myWriter2 = new StringWriter with FilterWriter with UpperWriter
println(myWriter1 write "Hello World!")
println(myWriter2 write "Hello World!")
在代码中定义了一个抽象类和三个trait。
其中抽象类Writer仅定义了一个抽象方法,并没有提供具体的实现。因此继承抽象类Writer的trait必须要实现write方法。
UpperWriter的write方法实现了将传入的英文字符转为大写;
FilterWriter的write方法实现了将小写的“o”替换为“-”;
StringWriter则只是将传入的字符串原样返回。
看一下上面的代码的执行结果:

验证了我们的说法:延迟绑定就是先混入的trait会后执行。
myWriter1的执行顺序:FilterWriter –> UpperWriter –> StringWriter;
myWriter2的执行顺序:UpperWriter –> FilterWriter –> StringWriter。
从trait的延迟绑定很容易会想到java的父类与子类的初始化顺序。又或者是java中的责任链模式。因此想想用java来实现这一点并不难:可以采用不同顺序的责任链,也可以是使用不同的继承顺序来实现。
再者,从这两节可以看出来scala中的trait和抽象类并无多大差别:
- 都可以有普通方法和抽象方法;
- 都可以有普通成员变量和抽象变量;
- 抽象类能做的事情trait都能做。
那他们的差别在哪儿呢:
- trait可以多重混入,抽象类只能单继承;
- 抽象类可以定义构造函数;
- trait可以混入实例,抽象类不可以。
那什么时候用trait,什么时候用抽象类呢:
- 优先使用trait。一个类扩展多个trait是很方便的,但却只能扩展一个抽象类。
- 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而trait不行。例如,你不能说trait t(i: Int) {},参数i是非法的。
参考文档:
https://twitter.github.io/scala_school/zh_cn/basics.html
http://www.artima.com/pins1ed/traits.html#12.7
##############
scala学习手记34 - trait方法的延迟绑定的更多相关文章
- scala学习手记31 - Trait
不知道大家对java的接口是如何理解的.在我刚接触到接口这个概念的时候,我将接口理解为一系列规则的集合,认为接口是对类的行为的规范.现在想来,将接口理解为是对类的规范多少有些偏颇,更恰当些的观点应该是 ...
- scala学习手记32 - trait选择性混入
继续上一节. 狗当然是人类的好朋友.但是藏獒呢?这玩意儿又蠢又笨又凶狠,肯定不能算很多人的好朋友了.其实,刚才那句话还可以修正一下下:我们接受的狗才是我们的好朋友. 用程序怎么实现呢?在java里面, ...
- scala学习手记33 - 使用trait进行装饰
在上一节看到了scala的在实例一级的选择性混入就不得不感叹scala在语法上的扩展性.就通过这样一个特性scala简化了很多在java中的编程概念和设计模式. 比如说在java中常用的组合,以及装饰 ...
- scala学习手记20 - 方法返回类型推断
除了推演变量的类型,scala也会推演方法的返回类型.不过这里有一处需要注意:方法返回类型的推演依赖于方法的定义方式.如果用等号"="定义方法,scala就会推演方法返回类型:否则 ...
- Scala学习笔记--特质trait
http://outofmemory.cn/scala/scala-trait-introduce-and-example 与Java相似之处 Scala类型系统的基础部分是与Java非常相像的.Sc ...
- scala学习手记13 - 类继承
在scala里,类继承有两点限制: 重写方法需要使用override关键字: 只有主构造函数才能往父类构造函数中传参数. 在java1.5中引入了override注解,但不强制使用.不过在scala中 ...
- scala学习手记2 - scala中的循环
先来看一段Java中的循环: for (int i = 1; i < 4; i++) { System.out.print(i + ","); } 毫无疑问,scala可以让 ...
- PHP 面向对象编程和设计模式 (2/5) - 静态变量、属性和方法及延迟绑定
PHP高级程序设计 学习笔记 2014.06.10 Static(静态)关键字用来定义静态方法和属性,static 也可用于定义静态变量以及后期静态绑定. 1.静态变量 static variable ...
- scala学习手记38 - 方法命名约定和for表达式
方法命名约定 之前在学习<运算符重载>一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级.现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例. ...
随机推荐
- 160725、Java Map按键排序和按值排序
按键排序(sort by key) jdk内置的Java.util包下的TreeMap<K,V>既可满足此类需求,原理很简单,其重载的构造器之一 有一个参数,该参数接受一个比较器,比较器定 ...
- git --fast-version-control
--distributed-is-the-new-centralized 读二进制文件 python 读doc xls 几乎所有的版本控制系统都以某种形式支持分支.使用分支意味着你可以把你的工作从 ...
- IO流入门-第十三章-File相关
/* java.io.File 1.File和流无关,不能通过该类完成文件的读写 2.File是文件和目录路径名的抽象变现形式. */ import java.io.*; public class F ...
- SpringMVC 运行流程以及与Spring 整合
1. 运行流程 2. Spring 和 SpringMVC 整合 // 1. 导入 jar 包 // 2. 配置 web.xml <!-- 配置 Spring 的核心监听器 --> < ...
- Diango思维图
1,http 2,Django生命周期 3,Django部分命令 4,待续...
- Java中Collections和Collection的区别
java.util.Collection Collection 层次结构 中的根接口.Collection 表示一组对象,这些对象也称为 collection 的元素.一些 collection 允许 ...
- (转)java类到底是如何加载并初始化的?
Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...
- struts2的HelloWorld的基本过程
login.jsp中 <form action="Login"... 该页面提交后, web.xml中设置的过滤器会起作用 <filter> ...
- java 多线程 day06 threadLocal
import java.util.HashMap;import java.util.Map;import java.util.Random; /** * Created by chengtao on ...
- Python(文件处理)
二.基本操作 #r''------------------>> r:原生字符串,不判断符号的含义#文件处理 f=open(r’c:\a.txt’,’r’,encoding=’utf-8’) ...