最近学习了scala特质的章节简单配合着视频进行了反编译分析。
1当trait只有抽象方法,没有非抽象方法时
package day07
object demo4 {
def main(args: Array[String]): Unit = {
val person = new Student()
person.say()
person.run()
}
}
trait Person{
def say()
def run()
}
class Student extends Person {
override def say(): Unit = {
println("你好")
}
override def run(): Unit = {
println("学生被罚跑步")
}
}
java 底层很简单 生成了一个接口Person ,然后生成了Student继承了person 并实现了方法
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\001Q1q!\001\002\021\002G\005QA\001\004QKJ\034xN\034\006\002\007\005)A-Y=1o\r\0011C\001\001\007!\t9!\"D\001\t\025\005I\021!B:dC2\f\027BA\006\t\005\031\te.\037*fM\")Q\002\001D\001\035\005\0311/Y=\025\003=\001\"a\002\t\n\005EA!\001B+oSRDQa\005\001\007\0029\t1A];o\001")
public interface Person {
void say();
void run();
}
package day07;
import scala.Predef$;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\001q1A!\001\002\001\013\t91\013^;eK:$(\"A\002\002\013\021\f\027\020M\034\004\001M\031\001A\002\007\021\005\035QQ\"\001\005\013\003%\tQa]2bY\006L!a\003\005\003\r\005s\027PU3g!\tia\"D\001\003\023\ty!A\001\004QKJ\034xN\034\005\006#\001!\tAE\001\007y%t\027\016\036 \025\003M\001\"!\004\001\t\013U\001A\021\t\f\002\007M\f\027\020F\001\030!\t9\001$\003\002\032\021\t!QK\\5u\021\025Y\002\001\"\021\027\003\r\021XO\034")
public class Student
implements Person
{
public void say() { Predef$.MODULE$.println("); }
public void run() { Predef$.MODULE$.println("); }
}
如果有抽象方法和非抽象方法,继承类实现了抽象方法呢
package day07
object demo4 {
def main(args: Array[String]): Unit = {
val person = new Student()
person.say()
person.run()
}
}
trait Person{
def say()
def run(): Unit ={
println("老师跑步")
}
}
class Student extends Person {
override def say(): Unit ={
println("你好")
}
}
java代码如下
同样底层现有了个personl 接口
package day07;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\001Y1q!\001\002\021\002\007\005QA\001\004QKJ\034xN\034\006\002\007\005)A-Y=1o\r\0011C\001\001\007!\t9!\"D\001\t\025\005I\021!B:dC2\f\027BA\006\t\005\031\te.\037*fM\")Q\002\001C\001\035\0051A%\0338ji\022\"\022a\004\t\003\017AI!!\005\005\003\tUs\027\016\036\005\006'\0011\tAD\001\004g\006L\b\"B\013\001\t\003q\021a\001:v]\002")
public interface Person {
void say();
void run();
}
接着是不同之处了,java底层生成了一个person$class抽象类并写下了一个同名run方法
package day07;
import scala.Predef$;
public abstract class Person$class
{
public static void $init$(Person $this) {}
public static void run(Person $this) { Predef$.MODULE$.println("老师跑步"); }
}
最后Student类实现了Person类重写了抽象方法,对于非抽象方法直接调用了抽象类的方法
package day07;
import scala.Predef$;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\001i1A!\001\002\001\013\t91\013^;eK:$(\"A\002\002\013\021\f\027\020M\034\004\001M\031\001A\002\007\021\005\035QQ\"\001\005\013\003%\tQa]2bY\006L!a\003\005\003\r\005s\027PU3g!\tia\"D\001\003\023\ty!A\001\004QKJ\034xN\034\005\006#\001!\tAE\001\007y%t\027\016\036 \025\003M\001\"!\004\001\t\013U\001A\021\t\f\002\007M\f\027\020F\001\030!\t9\001$\003\002\032\021\t!QK\\5u\001")
public class Student
implements Person
{
public void run() { Person$class.run(this); } public Student() { Person$class.$init$(this); }
public void say() { Predef$.MODULE$.println("你好"); }
}
最后如果抽象方法和非抽象方法都重写呢
package day07
object demo4 {
def main(args: Array[String]): Unit = {
val person = new Student()
person.say()
person.run()
}
}
trait Person{
def say()
def run(): Unit ={
println("老师跑步")
}
}
class Student extends Person {
override def say(): Unit ={
println("你好")
}
override def run(): Unit ={
println("学生被罚跑步")
}
}
直接看代码
package day07;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\001Y1q!\001\002\021\002\007\005QA\001\004QKJ\034xN\034\006\002\007\005)A-Y=1o\r\0011C\001\001\007!\t9!\"D\001\t\025\005I\021!B:dC2\f\027BA\006\t\005\031\te.\037*fM\")Q\002\001C\001\035\0051A%\0338ji\022\"\022a\004\t\003\017AI!!\005\005\003\tUs\027\016\036\005\006'\0011\tAD\001\004g\006L\b\"B\013\001\t\003q\021a\001:v]\002")
public interface Person {
void say();
void run();
}
package day07;
import scala.Predef$;
public abstract class Person$class
{
public static void $init$(Person $this) {}
public static void run(Person $this) { Predef$.MODULE$.println("老师跑步"); }
}
package day07;
import scala.Predef$;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "\006\001q1A!\001\002\001\013\t91\013^;eK:$(\"A\002\002\013\021\f\027\020M\034\004\001M\031\001A\002\007\021\005\035QQ\"\001\005\013\003%\tQa]2bY\006L!a\003\005\003\r\005s\027PU3g!\tia\"D\001\003\023\ty!A\001\004QKJ\034xN\034\005\006#\001!\tAE\001\007y%t\027\016\036 \025\003M\001\"!\004\001\t\013U\001A\021\t\f\002\007M\f\027\020F\001\030!\t9\001$\003\002\032\021\t!QK\\5u\021\025Y\002\001\"\021\027\003\r\021XO\034")
public class Student
implements Person
{
public Student() { Person$class.$init$(this); }
public void say() { Predef$.MODULE$.println("你好"); }
public void run() { Predef$.MODULE$.println("学生被罚跑步"); }
可以看出 student类继承了person类重写了say方法和run方法
最后我们可以看出在scala中特质可以有抽象方法和非抽象方法,在java底层实际上是生成了一个interface和一个抽象类,如果继承类重写了抽象方法,则直接重写,如果重写了非抽象方法则直接从抽象类中调用那个静态的非抽象方法