trait底层原理分析
来源:互联网 发布:cad软件正版价格 编辑:程序博客网 时间:2024/06/05 03:24
本文阐述了Scala语言中, trait的底层实现原理.
trait中的变量是抽象变量
************--------------------------trait(1):抽象变量---------------------------**************
trait Property{ var name:String val value:String}class Test1 extends Property{ override var name = "Test1" //override可加可不加; override val value = "Test2" //override可加可不加;}
Java里的实现:
public abstract interface Property{ public abstract String name(); public abstract void name_$eq(String paramString); public abstract String value();}public class Test1 implements Property{ private String name = "Test1"; private final String value = "Test2"; public String name() { return this.name; } public void name_$eq(String x$1) { this.name = x$1; } public String value() { return this.value; }}结论:1 完全和java相等的代码; Property是一个interface, name和value都在子类Test1里面定义, 且name有存取方法,value只有取方法;
2 也可看出, trait里面也可以定义var变量;
trait中的变量是实体变量, 子类改写
************--------------------------trait(2): var的override---------------------------**************
trait Property{ var name:String = "Property" val value:String = "OOO"}class Test1 extends Property{ override var name = "Test1" //会报错:overriding variable name in trait Property of type String; variable name cannot override a mutable variable; override val value = "Test2" //val value = "Test2" //不加override会报错;}看来trait中非抽象的var不能在子类里重新赋值;
trait中有可执行语句调用变量, 子类会改写变量
************--------------------------trait(3): trait里面有可执行语句---------------------------**************trait Property{ val name:String = "name"; val value:String = "value"; println("123")}class Test1 extends Property{ override val name = "Test1" override val value = "Test2"}
转化为Java的语句:
public abstract class Property$class{ public static void $init$(Property $this) { Predef..MODULE$.println("123"); $this.Property$_setter_$name_$eq("Property"); $this.Property$_setter_$value_$eq("OOO"); }}public abstract interface Property{ public abstract void Property$_setter_$name_$eq(String paramString); public abstract void Property$_setter_$value_$eq(String paramString); public abstract String name(); public abstract String value();}public class Test1 implements Property{ private final String name; private final String value; public void Property$_setter_$name_$eq(String x$1) { } public void Property$_setter_$value_$eq(String x$1) { } public String name() { return this.name; } public String value() { return this.value; } public Test1() { Property.class.$init$(this); this.name = "Test1"; this.value = "Test2"; }}这时的改动就大了:
1 由于trait里面多了可执行语句(无论是println还是变量赋值),而非单纯的抽象变量声明, 所以多出了Property$class;
2 Test1()的构造函数里面会先调用Property$class的init(), 等于会先执行trait里的语句!
3 由于trait里面有对变量定义的语句,所以trait等于多了对2个变量的存取方法,且这4个方法需要子类实现;
4 由于Test1对name和value进行了override, 所以等于Test1重写了name和value的存取方法;
5 结论是: 如果在trait里面想对name和value进行读取,是读不到的,因为子类Test1用空方法重写了变量, 而且在调用init()方法后,才会为2个变量赋值;
Test1() -> trait()的执行语句 -> Test1对变量的赋值语句;
结论:
1 trait里面是否有可执行语句, 决定了: 是否会在子类Test1()构造方法里调用trait的可执行语句;
2 trait里面是否对变量赋值(即是否为抽象类型), 决定了: 变量是否有"写访问方法";
3 子类Test1里面是否有override val name = "Test1"重写语句, 决定了: 是否会重写trait里面的"写访问方法";
4 当trait里面是抽象类型时, 子类里的override修饰符可以不写;
5 trait里面如果有可执行语句,那么会在子类构造器的其他语句执行前执行, 这样, trait里定义的变量, 在执行trait的语句时就不会正确赋值;
trait中有可执行语句调用变量, 子类会改写变量
************--------------------------trait(4): 使用with改善上面的问题---------------------------**************
class Test1 extends { val name = "Test1xxxx" val value = "Test2"} with Property用jad工具可看到:jad -p /Users/umeng/workspace_scala/20160210/out/production/20160210/Test1.classpublic class Test1 implements Property{ public String name() { return name; } public String value() { return value; } public Test1() { String name = "Test1xxxx"; this.name = name; String value = "Test2"; this.value = value; super(); Property.class.$init$(this); } private final String name; private final String value;}可看到,会先设置name和value,然后才会调用父类构造方法,然后才会调用init(); 这样在调用Property的执行语句时, name和value就已经设置好了;
见<<scala编程>>P270.
0 0
- trait底层原理分析
- java中的Arrays.asList()底层原理分析
- Haproxy反向代理MySQL底层原理分析
- MyBatis动态SQL底层原理分析
- MyBatis 动态 SQL 底层原理分析
- Binder底层原理,aidl.java文件分析
- Kafka Consumer底层原理分析【Kafka系列】
- HashMap之entrySet( )底层实现原理分析
- HashMap的底层原理及源码分析
- MyBatis动态SQL底层原理分析
- 容器Map和HashMap底层原理分析
- HashMap的底层原理分析二
- Trait
- trait
- Trait
- trait
- trait
- trait
- 第6章创建函数-----------(select命令操作实例)
- Java中Properties类的操作
- iBatis.Net 简介及运行环境
- 451. Sort Characters By Frequency
- 理解泛型和通配符?
- trait底层原理分析
- 【Java 教程】
- PAYPAL EC快速支付接入汇总
- 如何使用github管理代码
- 【Abertay阿伯泰大学毕业】
- 解决COM端口号与工具比匹配的问题
- 序列操作(线段树,模板)
- openTSDB+HBase+ZK遇到的坑汇总
- 通过@ImportResource实现xml配置的装载