Scala:trait

Scala开篇(目录)

在Scala中有一个trait类型,它可以被继承,而且支持多重继承,其实它更像我们熟悉的接口(interface),但它与接口又有不同之处是:
trait中可以写方法的实现,interface不可以(java8开始支持接口中允许写方法实现代码了),这样看起来trait又很像抽象类(abstract),一会我们会通过反编译,看看Scala中对trait是怎样处理的,先来看看trait的使用。

//声明一个 trait
trait TraitBase{
  def add(x:Int,y:Int): Int ={
    return x+y
  }
}
//TraitTest 继承自 TraitBase
class TraitTest extends TraitBase{
//重写父类的方法
  override def add(x:Int,y:Int): Int ={
    return x+y*10
  }
}

//如果需要调用父类的方法,使用super访问父类
class TraitTest extends TraitBase{
  override def add(x:Int,y:Int): Int ={
    return super.add(x,y)*10
  }
}

//使用
    val test = new TraitTest
    println(test.add(4,5))

对于多重继承,我们使用 with 关键字

trait A{
  def FA(): Unit ={
    println("FA")
  }
}
trait B{
  def FB(): Unit ={
    println("FB")
  }
}
class C{
  val content=null
}
//多重继承
class D extends C with A with B{
//这里不需要必须实现trait中的方法
}

看完了使用,我们看看编译器把trait编译成什么样的java对象了。编译后有两个文件(TraitBase$class.class和TraitBase.class)
先来看看TraitBase.class

/**很熟悉吧,interface,看来trait还是跟interface有共性*/
public abstract interface TraitBase
{
  public abstract int add(int paramInt1, int paramInt2);
}

再看看TraitBase$class.class

/**抽象类
它内部都是static的静态方法,但是大家注意
每个方法都带有一个参数,TraitBase 对象,通过这个对象,可以访问实际对象中定义的变量和方法
*/
public abstract class TraitBase$class
{
  public static int add(TraitBase $this, int x, int n)
  {
    return x + n;
  }

  public static void $init$(TraitBase $this)
  {
  }
}

对于继承自trait的TraitTest,反编译结果如下

/**中规中矩的接口继承*/
public class TraitTest  implements TraitBase
{
  public int add(int x, int n)
  {
  //调用的是TraitBase$class类中的add方法,并传递了自己这个实例对象
    return TraitBase.class.add(this, x, n); 
  } 
  //初始化
  public TraitTest() 
  { 
      TraitBase.class.$init$(this); 
  }

}

属性的访问,假如有下面的Scala代码

trait TraitBase{
  val content = "this is trait test"
}

class TraitTest extends TraitBase{
  def Foo(): Unit ={
    println(content)
  }
}

反编译结果
TraitBase.class

public abstract interface TraitBase
{
/**编译器自动增加了两个接口,对content属性赋值和取值*/

  //写接口,编译器自动命名,就是我们常用的stter
  public abstract void scala$test$TraitBase$_setter_$content_$eq(String paramString);
  //读接口,就是我们常用的getter
  public abstract String content();
}

TraitBase$class.class

public abstract class TraitBase$class
{
//初始化,初始化变量
  public static void $init$(TraitBase $this)
  {
    $this.scala$test$TraitBase$_setter_$content_$eq("this is trait test");
  }
}

看来trait最终编译为interface和abstract class的两个文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bdmh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值