探索Scala(2)-- Traits
来源:互联网 发布:unity3d自发光shader 编辑:程序博客网 时间:2024/05/16 09:50
本文记录我对Scala语言Traits的一些理解。
trait >= interface
Scala语言没有接口(Interface)的概念,取而代之的,是功能更加强大的Trait。因此,interface在Scala语言里并不是关键字,我们可以自由的使用它,如下面这段代码所示:
但是要注意,上面的代码虽然是合法的Scala代码,能编译出ScalaObject.class。但是如果想在Java里正常使用这个class的话,就会遇到问题。
没有具体方法的Trait会被编译成接口
如果一个Trait没有定义任何有具体实现的方法,那么它和接口是等价的。换句话说,如果一个Trait的所有方法(如果有的话)全都是抽象的,那么Scala会把它编译成Java接口。比如下面这个没有任何方法的TraitA:
会被编译成TraitA.class,分析class文件可以知道,它其实等价于下面的Marker接口:
public interface TraitA {}再比如下面这个有两个抽象方法的TraitB:
会被编译为:
public interface TraitB { public int m1(); public int m2(int arg);}
有具体方法的Trait会被编译成两个class文件
以下面这个TraitC为例:
编译之后得到两个class文件:TraitC.class和TraitC$class.class。分析class文件可以知道,TraitC.class实际上是一个接口,如下所示:
public interface TraitC { public int m3(int arg);}方法实现在TraitC$class.class里,如下所示:
public abstract class TraitC$class { public static int m3(TraitC t, int arg) { return 1; } public static void $init$() { //return; }}由此可知:
- Trait会被编译为等价的接口
- 如果Trait有具体方法,则这些方法会被复制到相应的$class类里,并且有下面两处变动:
- 方法变为static
- Trait实例被插入到参数列表的最开始
字段(Fields)
如果Trait定义了字段呢?比如下面这个TraitD:
编译之后,仍然会得到两个class文件,如下所示:
public interface TraitD { public int f1(); public void f1_$eq(int i);}public abstract class TraitD$class { public static void $init$(TraitD t) { t.f1_$eq(1); }}由此可知:
- Trait仍然被编译成了等价的接口,但var字段被替换成了一对儿getter/setter方法。需要注意的是,这对getter/setter方法并没有按照JavaBean风格来命名
- 相应的$class类里只有一个$init$方法
Mix in Traits
下面通过一个类来观察一下mix in上面提到的Traits之后,会发生什么:
下面是反编译之后的MyClass(Java)代码:
public class MixedIn implements TraitA, TraitB, TraitC, TraitD { private int f1; public MixedIn() { TraitC$class.$init$(this); TraitD$class.$init$(this); } public int f1() { return this.f1; } public void f1_$eq(int val) { this.f1 = val; } public int m1() { return 0; } public int m2(int arg) { return arg; } public int m3(int arg) { return TraitC$class.m3(this, arg); }}
分析如下:
- TraitA没有定义任何方法,所以只是继承了接口
- TraitB有两个抽象方法(m1、m2),所以我们必须自己实现这两个方法
- TraitC有一个具体方法(m3),被Scala编译器实现
- TraitD定义了一个字段,也被编译器实现
- 编译器还生成了一个构造函数,调用了TraitC和TraitD的$init$方法
0 0
- 探索Scala(2)-- Traits
- scala——traits
- Scala——Traits
- Scala之Traits
- Scala(3)-Traits
- C++ traits(2)
- 探索Scala(6)-- Tuples
- 探索Scala(7)-- 字段
- 探索Scala(8)-- 关键字
- 探索Scala(1)-- 运算符重载
- 探索Scala(3)-- 单例对象
- 探索Scala(4)-- Case Classes
- 探索Scala(5)-- 基本类型
- Scala 的Value Class 和 Universal Traits
- 第十节 Scala类层次结构、Traits初步
- 【深度探索STL】详解 traits 编程技法
- 《Effective C++》再次探索traits技法
- c++ type traits 2
- Windows XP 搭建PPPoE服务器_计算机软件及应用_IT/计算机_专业资料
- CSDN 新栏目的添加
- 黑马程序员_异常
- 面向接口编程详解(三)
- Windows 10 技术预览版:通过组策略来更改Windows 更新自动检查下载和安装设置
- 探索Scala(2)-- Traits
- CSS中关于属性值继承的小问题
- Lubuntu 安装输入法有黑块问题的解决方法
- M2_REPO解决mvn无错,eclipse有错问题
- Storm 实现滑动窗口计数和TopN排序<转>
- Android BlueDroid(一):BlueDroid概述
- 漫谈算法(一)如何证明贪心算法是最优 using exchange argument
- 第一个c上机报告
- android内存溢出解决方案!很详细