1. 简介
在scala中,一个类只能单继承一个类,但是一个类却可以多继承特质。从内容上来看,抽象类和特质中包含的内容是完全一致的,都可以有属性、抽象方法、普通方法(有具体实现的方法)。那在底层java代码是如何实现特质的多继承的呢。
2. 反编译代码查看
2.1 特质中只包含抽象方法
2.1.1 特质Trait03 的scala代码
trait Trait03 {
def sayHi()
}
2.1.2 反编译 Trait03.class 代码
public abstract interface Trait03 {
public abstract void sayHi();
}
2.1.3 特质子类 sheep的scala代码
class sheep extends Trait03 {
override def sayHi(): Unit = {
println("say Hi~~~")
}
}
2.1.4 特质子类sheep反编译 sheep.class 代码
public class sheep implements Trait03 {
public void sayHi() {
Predef..MODULE$.println("say Hi~~~");
}
}
2.1.5 代码分析
当特质中只有抽象方法时,在java实现中,该特质会被编译为抽象接口 public abstract interface ,该接口中包含抽象方法。scala中继承了特质的子类,在java实现中是实现对应的抽象接口,然后实现其中的抽象方法。
2.2 特质中包含抽象方法和普通方法
2.2.1 特质Trait03 的scala代码
trait Trait03 {
def sayHi()
def sayHello(): Unit = {
println("say Hello~~~")
}
}
2.2.2 反编译 Trait03.class 和 Trait03$class.class 代码
public abstract interface Trait03 {
public abstract void sayHi();
public abstract void sayHello();
}
public abstract class Trait03$class {
public static void sayHello(Trait03 $this) {
Predef..MODULE$.println("say Hello~~~");
}
public static void $init$(Trait03 $this) {
}
}
2.2.3 特质子类 sheep的scala代码
class sheep extends Trait03 {
override def sayHi(): Unit = {
println("say Hi~~~")
}
}
2.2.4 特质子类sheep反编译 sheep.class 代码
public class sheep implements Trait03 {
public void sayHello() {
Trait03$class.sayHello(this);
}
public sheep() {
Trait03$class.$init$(this);
}
public void sayHi() {
Predef..MODULE$.println("say Hi~~~");
}
}
2.2.5 代码分析
- 当特质中同时包含抽象方法和普通方法时,特质底层java实现会将其拆分为一个抽象接口 Trait03 和一个抽象类 Trait03$class 。
- 抽象类中包含特质中的普通方法,并且将其设置为静态方法,提供对应的具体实现。同时提供静态的初始化方法,参数类型为特质本身。该初始化方法实现为空,可能只是为了解决多线程安全问题(现在原因未知)?
- 抽象接口中包含特质中的抽象方法
2. 特质子类继承特质后,底层java的实现:
1. 现特质的抽象接口,然后在内部实现抽象接口的抽象方法。
2. 提供实现子类的主构造方法,内部调用特质对应的抽象类中的初始化方法,将子类本身作为参数进行传递。
3. 对于特质中的普通方法,特质子类底层java提供同名方法,实际是调用抽象类对应的静态方法,将子类本身作为参数进行传递。
3. 总结
当特质同时包含抽象方法和普通方法时,底层java实现会将其拆分,将抽象方法放到对应的抽象接口中,将普通方法放到对应的抽象类中,并提供对应的静态方法实现。因此在scala中可以实现特质的多继承,其内部原因就是特质多继承只是底层java多实现其多个特质对应的抽象接口,而对于其普通方法,子类只是静态调用特质对应的抽象类中的静态方法。
所以scala特质可以多继承,但是抽象类却不可以多继承,因为抽象类属于类。