scala中使用特质中的抽象字段和实际字段
Scala中,trait相當(dāng)于Java中的接口,遇到需要使用Java接口的場景時(shí),你就在scala中可以使用trait了。
?
我們知道Java中你可以實(shí)現(xiàn)多個(gè)接口,那么Scala中,你也可以繼承多個(gè)trait
?
Java中接口不能有自己的實(shí)現(xiàn)方法,但是Scala中trait可以包含自己的實(shí)現(xiàn)方法
?
一 特質(zhì)用作接口
接口的作用:對(duì)行為進(jìn)行規(guī)范,具有解耦的作用,滿足業(yè)務(wù)系統(tǒng)依賴倒置的設(shè)計(jì)原則
注意:
第一:如果只需要一個(gè)那么使用extends,要實(shí)現(xiàn)多個(gè)trait,需要使用with
第二:抽象類繼承trait,可以不給具體的實(shí)現(xiàn),實(shí)現(xiàn)可以交給子類去做
?
traitBaseSoundPlayer{
??? def play(music:String)
??? def close
??? def puase(music:String,time:Int)
??? def stop
??? def resume
}
二 使用特制中的抽象字段和實(shí)際子段
在特質(zhì)中定義抽象字段和實(shí)際子段,以便于繼承該特質(zhì)的類都可以使用這些字段
?
聲明一個(gè)變量,賦一個(gè)初始值,就是一個(gè)實(shí)際字段,否則這個(gè)字段就是抽象字段
注意:
#抽象字段不需要加override,而且變量修飾符應(yīng)該和trait一樣,因?yàn)?/span>trait不會(huì)針對(duì)抽象字段產(chǎn)生get set方法,所以子類就需要提供變量修飾符
#實(shí)際字段如果是var變量,不需要加override關(guān)鍵字,那么子類重寫不需要加變量修飾符,因?yàn)楸旧磉@個(gè)字段就有set方法,所以可以子類就可以直接修改
#實(shí)際子段如果是val變量,需要加override關(guān)鍵字,那么子類重寫必須加上變量修飾符,因?yàn)?/span>trait中的該字段沒有set方法,如果你想改變這個(gè)值,就相當(dāng)于你要在子類重新寫一個(gè),所以需要加override
trait PizzaTrait {/*抽象字段*/var numToppings:Intval ptype:String/*實(shí)際字段*/var size = 14val maxNumToppings = 10 }class Pizza extends PizzaTrait{/*抽象字段不需要加override,而且變量修飾符應(yīng)該和trait一樣*/var numToppings: Int = 4val ptype: String = "thin"/*實(shí)際字段不需要加override,而且不需要加變量修飾符*/size = 16override val maxNumToppings = 20 }?
三 像Java抽象類一樣使用特質(zhì)
抽象類:可以有抽象字段和抽象方法,也可以有非抽象字段和非抽象方法
注意:
如果一個(gè)繼承了特質(zhì),但是并沒有實(shí)現(xiàn)其抽象字段或者抽象方法,那么該類必須加abstract字段,意思就是說這個(gè)類必須為抽象類
?
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")} }?
四 簡單混入特質(zhì)
說的明白些:其實(shí)就是繼承抽象類并且混入withtrait
類似于Java中一個(gè)類繼承了抽象類,實(shí)現(xiàn)了某一個(gè)接口
?
五 通過繼承來限制特質(zhì)的使用范圍
特質(zhì)可以限定哪些類來使用是可以的,比如說限定某些繼承了某個(gè)類或者某個(gè)特質(zhì)的類來使用這個(gè)trait
語法格式:
trait [traitname] extends [superthings]
一般情況下,某一個(gè)類可以隨便繼承其他父類,和混入其他的trait,但是有的時(shí)候,你只希望混入繼承了該父類的trait才可以混入,否則混入不進(jìn)來,這也就是限制了不能隨意的混入
class StarfleetComponent class RomulanStuff trait StarfleetWrapCore1? extends StarfleetComponentclass Starship extends StarfleetComponent with StarfleetWrapCore1 //編譯報(bào)錯(cuò),因?yàn)?/span>StarfleetWrapCore 沒有繼承RomulanStuff class Warbird1 extends RomulanStuff with StarfleetWrapCore1 /*如果我們這樣修改就沒有問題了*/ trait StarfleetWrapCore2? extends RomulanStuff class Warbird2 extends RomulanStuff with StarfleetWrapCore2?
六 限定特質(zhì)只可用于指定類型的子類
通過語法this:指定類型 => 然后指定所允許混入的類或者其子類才可以混入該trait
?
class BaseType class ParentType trait MyTrait {/*** 指定該trait只能被BaseType的子類可以混入* 不是BaseType的子類是不可以混入這個(gè)trait的*/this:BaseType => }class ConcreteType extends BaseType with MyTrait /*所以這里會(huì)報(bào)錯(cuò)*/ class ImplementType extends? ParentType with MyTrait?
七 保證特質(zhì)只能被添加到只有一個(gè)特定方法的類型
允許特質(zhì)混入到一個(gè)有給定簽名的方法的類型(類,抽象類或者特質(zhì))
解決辦法:
trait 特質(zhì)名字{
????? this:{def 函數(shù)名(參數(shù):數(shù)據(jù)類型):返回值類型} =>
}
trait Limit {this:{ def validate(passwd:String):Boolean} => }class Define extends Limit{//必須有這樣的方法簽名才可以混入Limit特質(zhì)def validate(passwd:String):Boolean = {true} }?
八 為對(duì)象實(shí)例添加特質(zhì)
有時(shí)候,我們可能只是想給某些對(duì)象添加特質(zhì),而不是針對(duì)類,即基于該類的對(duì)象,有的可以添加特質(zhì),有的不可以
語法格式:
new 類名字 with trait名字
class DavidBannertrait Angry{println("You won't like me ...") }object Test extends App{val hunk = new DavidBanner with Angry }?
九 向特質(zhì)一樣繼承Java接口
Scala中,我們可以像繼承特質(zhì)一樣繼承Java接口,通過with可以多繼承,然后在類中實(shí)現(xiàn)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("奔跑中.....")} }總結(jié)
以上是生活随笔為你收集整理的scala中使用特质中的抽象字段和实际字段的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Akka并发编程——第八节:Actor模
- 下一篇: define,require的基本用法