欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

scala中使用特质中的抽象字段和实际字段

发布时间:2024/1/23 编程问答 58 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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
}

trait BaseVedioPlayer {def display(vedio:String) } class MP4SoundPlayer extends BaseSoundPlayer with BaseVedioPlayer{override def play(music: String): Unit = {println("playing music "+music)}override def stop: Unit = {println("stop to play")}override def puase(music: String, time: Int): Unit = {println("pause to play music "+music+" for "+time+" s")}override def close: Unit = {println("closed  player")}override def resume: Unit = {println("resume to play")}override def display(vedio: String): Unit = {println("this player also watch the vedio "+vedio)} }     abstract class BasePlayer extends BaseSoundPlayer with BaseVedioPlayer{}  

二 使用特制中的抽象字段和实际子段

在特质中定义抽象字段和实际子段,以便于继承该特质的类都可以使用这些字段

 

声明一个变量,赋一个初始值,就是一个实际字段,否则这个字段就是抽象字段

注意:

#抽象字段不需要加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中使用特质中的抽象字段和实际字段的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。