Scala:trait

原创 2015年12月14日 14:00:34

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的两个文件

版权声明:本文为博主原创文章,未经博主允许不得转载。

Scala入门到精通——第十一节 Trait进阶

本节主要内容 trait构造顺序 trait与类的比较 提前定义与懒加载 trait扩展类 self type 1 trait构造顺序在前一讲当中我们提到,对于不存在具体实现及字段的trait,它最终...

SCALA 集合框架文档翻译-Trait Traversable

Traversable 特质 SCALA集合类层级的顶端是 Traversable 特质。它只有一个抽象方法 foreach: def foreach[U](f: Elem => U) 实现 Tr...

Scala 之 trait 关键字

这里的trait字面意思是特质或者特征,这个词翻译成特征比较合适。它的意义和java,c#中接口很类似。但是trait支持部分实现,也就是说可以在scala的trait中可以实现部分方法。下面我们以一...

scala基础-----Trait Traversable

scala基础-----Trait Traversable

Scala trait介绍

Scala trait介绍及实践。
  • yyywyr
  • yyywyr
  • 2015年12月07日 22:40
  • 1008

scala学习(十五)——trait

scala学习(十五)——trait 下面是一个trait的简单例子,里面包含的trait的基本用法,trait的继承: trait Logger{ //这里在java的接口中只能声明为静态的...

scala基础之特质trait

Scala中,trait相当于Java中的接口,遇到需要使用Java接口的场景时,你就在Scala中可以使用trait了。   我们知道Java中你可以实现多个接口,那么Scala中,你也可以继承...

Java的接口与Scala的trait特质

今天说一说Java中的接口和Scala中的trait。一直就把特质当做半个接口用,因为确实挺像的,但仔细看,还是有很大区别的。 1.接口不会有构造器,特质可以有构造器,并且在实现类继承特质的...

Scala入门到精通——第十一节 Trait进阶

本节主要内容 trait构造顺序trait与类的比较提前定义与懒加载trait扩展类self type 1 trait构造顺序 在前一讲当中我们提到,对于不存在具体实现及字段的trait,它...

Scala学习笔记5--Trait

Scala-Trait Trait Trait就像一个拥有部分实现的接口,可以通过with关键字混入导类中。 trait Friend { val name: String d...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Scala:trait
举报原因:
原因补充:

(最多只允许输入30个字)