scala中使用特质中的抽象字段和实际字段
Scala中,trait相当于Java中的接口,遇到需要使用Java接口的场景时,你就在scala中可以使用trait了。
我们知道Java中你可以实现多个接口,那么Scala中,你也可以继承多个trait
Java中接口不能有自己的实现方法,但是Scala中trait可以包含自己的实现方法
一 特质用作接口
接口的作用:对行为进行规范,具有解耦的作用,满足业务系统依赖倒置的设计原则
注意:
第一:如果只需要一个那么使用extends,要实现多个trait,需要使用with
第二:抽象类继承trait,可以不给具体的实现,实现可以交给子类去做
traitBaseSoundPlayer{
def play(music:String)
def close
def puase(music:String,time:Int)
def stop
def resume
}
二 使用特制中的抽象字段和实际子段
在特质中定义抽象字段和实际子段,以便于继承该特质的类都可以使用这些字段
声明一个变量,赋一个初始值,就是一个实际字段,否则这个字段就是抽象字段
注意:
#抽象字段不需要加override,而且变量修饰符应该和trait一样,因为trait不会针对抽象字段产生get set方法,所以子类就需要提供变量修饰符
#实际字段如果是var变量,不需要加override关键字,那么子类重写不需要加变量修饰符,因为本身这个字段就有set方法,所以可以子类就可以直接修改
#实际子段如果是val变量,需要加override关键字,那么子类重写必须加上变量修饰符,因为trait中的该字段没有set方法,如果你想改变这个值,就相当于你要在子类重新写一个,所以需要加override
trait PizzaTrait {/*抽象字段*/var numToppings:Intval ptype:String/*实际字段*/var size = 14val maxNumToppings = 10 }class Pizza extends PizzaTrait{/*抽象字段不需要加override,而且变量修饰符应该和trait一样*/var numToppings: Int = 4val ptype: String = "thin"/*实际字段不需要加override,而且不需要加变量修饰符*/size = 16override val maxNumToppings = 20 }
三 像Java抽象类一样使用特质
抽象类:可以有抽象字段和抽象方法,也可以有非抽象字段和非抽象方法
注意:
如果一个继承了特质,但是并没有实现其抽象字段或者抽象方法,那么该类必须加abstract字段,意思就是说这个类必须为抽象类
trait Pet {var weight:Floatdef speakTo(who:String,sound:String){println("Towards "+who+", "+sound)}def actingCute }case class Cat(name:String) extends Pet{var color:String = ""var weight: Float = 0.0fdef this(cname:String,color:String,weight:Float){this(cname)this.color = colorthis.weight = weight}override def actingCute: Unit = {println(s"$name is acting cute");}def desc(): Unit = {println(s"I'm $name, my color is $color")} }case class Dog(name:String) extends Pet{var ptype:String = ""var weight: Float = 0.0fdef this(dname:String,ptype:String,weight:Float){this(dname)this.ptype = ptypethis.weight = weight}override def actingCute: Unit = {println(s"$name is acting cute");}def desc(): Unit = {println(s"I'm $name, my belongs to $ptype")} }
四 简单混入特质
说的明白些:其实就是继承抽象类并且混入withtrait
类似于Java中一个类继承了抽象类,实现了某一个接口
五 通过继承来限制特质的使用范围
特质可以限定哪些类来使用是可以的,比如说限定某些继承了某个类或者某个特质的类来使用这个trait
语法格式:
trait [traitname] extends [superthings]
一般情况下,某一个类可以随便继承其他父类,和混入其他的trait,但是有的时候,你只希望混入继承了该父类的trait才可以混入,否则混入不进来,这也就是限制了不能随意的混入
class StarfleetComponent class RomulanStuff trait StarfleetWrapCore1 extends StarfleetComponentclass Starship extends StarfleetComponent with StarfleetWrapCore1 //编译报错,因为StarfleetWrapCore 没有继承RomulanStuff class Warbird1 extends RomulanStuff with StarfleetWrapCore1 /*如果我们这样修改就没有问题了*/ trait StarfleetWrapCore2 extends RomulanStuff class Warbird2 extends RomulanStuff with StarfleetWrapCore2
六 限定特质只可用于指定类型的子类
通过语法this:指定类型 => 然后指定所允许混入的类或者其子类才可以混入该trait
class BaseType class ParentType trait MyTrait {/*** 指定该trait只能被BaseType的子类可以混入* 不是BaseType的子类是不可以混入这个trait的*/this:BaseType => }class ConcreteType extends BaseType with MyTrait /*所以这里会报错*/ class ImplementType extends ParentType with MyTrait
七 保证特质只能被添加到只有一个特定方法的类型
允许特质混入到一个有给定签名的方法的类型(类,抽象类或者特质)
解决办法:
trait 特质名字{
this:{def 函数名(参数:数据类型):返回值类型} =>
}
trait Limit {this:{ def validate(passwd:String):Boolean} => }class Define extends Limit{//必须有这样的方法签名才可以混入Limit特质def validate(passwd:String):Boolean = {true} }
八 为对象实例添加特质
有时候,我们可能只是想给某些对象添加特质,而不是针对类,即基于该类的对象,有的可以添加特质,有的不可以
语法格式:
new 类名字 with trait名字
class DavidBannertrait Angry{println("You won't like me ...") }object Test extends App{val hunk = new DavidBanner with Angry }
九 向特质一样继承Java接口
Scala中,我们可以像继承特质一样继承Java接口,通过with可以多继承,然后在类中实现java接口的方法
public interface Animal {public void speak(); } public interface Wagging {public void wag(); } public interface Running {public void run(); }class Tiger extends Animal with Wagging with Running{override def speak(): Unit = {println("吼吼")}override def wag(): Unit = {println("摇尾巴")}override def run(): Unit = {println("奔跑中.....")} }
总结
以上是生活随笔为你收集整理的scala中使用特质中的抽象字段和实际字段的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Akka并发编程——第八节:Actor模
- 下一篇: define,require的基本用法