17抽象类(abstractclass)与特质(trait)
抽象类:
抽象类与Java相似,只是Java中没有属性的抽象,scala可以有属性的抽象;
特质:
可以把特质理解成Java中升级版的接口
在Java中接口不能声明没有值的属性和有实现的方法,而Scala可以声明没有值的属性和有实现的方法;
重写:
重写与Java相似,只是Java中没有重写属性的概念,而scala可以重写属性;
特质和抽象类的使用区别:
只能继承一个抽象类,但可以实现多个特质。这点和Java一样;
下面分别详细说明
17.1抽象类定义特质需要用trait关键字;
特质可以包含抽象成员和非抽象成员,这与scala的抽象类类似,包含抽象成员时,不需要abstract关键字;
在Scala中,无论继承类还是继承Trait都是用exts关键字;
在重写特质的方法时,不需要给出override关键字;
packageday03traitFly{//定义普通属性valname:String="飞"//定义抽象属性valmaxFlyHigh:Int//定义普通方法defdescription={println("这是特质里面的普通方法")}//定义抽象方法defaction():Unit}classBirdextsFly{//重写抽象成员valmaxFlyHigh:Int=1000defaction():Unit={println("鸟用翅膀飞")}//重写非抽象成员overridevalname:String="火烈鸟"overridedefdescription:Unit={(s"${name}")action()println(s"最大飞行高度:${maxFlyHigh}")}}objectTraitTest{defmain(args:Array[String]):Unit={valbird=}}当不继承类直接实现一个特质,可以不用with直接用exts,实现多个特质的时候可以用多个with,但是必须先exts第一个
如:classT1extsT2withT3withT4
packageday03traitFly{//定义普通属性valname:String="飞"//定义抽象属性valmaxFlyHigh:Int//定义普通方法defdescription={println("这是特质里面的普通方法")}//定义抽象方法defaction():Unit}traitRun{defrun():Unit}classBirdextsFly{//重写抽象成员valmaxFlyHigh:Int=1000defaction():Unit={println("鸟用翅膀飞")}//重写非抽象成员overridevalname:String="火烈鸟"overridedefdescription:Unit={(s"${name}")action()println(s"最大飞行高度:${maxFlyHigh}")}}//实现多个特质用withclassAirPlaneextsFlywithRun{overridevalmaxFlyHigh:Int=10000overridedefaction():Unit={println("飞机用翅膀飞")}overridedefrun():Unit={println("飞机用轱辘跑")}overridedefdescription:Unit={()run()println(s"最大飞行高度:${maxFlyHigh}")}}objectTraitTest{defmain(args:Array[String]):Unit={valbird=("------------------")valplane=}}特质通过字段的初始化和其他特质体中的语句构成来实现构造的逻辑。
但特质不能new实例。
traitT1{//特质构造执行vala:String="aaa"println(a)deft1():Unit}traitT2{//特质构造执行valb:String="bbb"println(b)deft2():Unit}classT1SubextsT1withT2{//本类构造执行valc:String="ccc"println(c)deft1():Unit={println("dot1()")}deft2():Unit={println("dot2()")}}objectT1SubTest{defmain(args:Array[String]):Unit={//调用newT1Sub时,先执行T1的构造,再执行T2的构造,然后执行本类构造valt=()()}}//-----------运行结果-----------------aaabbbcccdot1()dot2()什么时候使用特质和抽象类?
使用角度
主次关系用抽象类,额外功能用特质,比如蜘蛛侠。
语法角度
1)优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
2)如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行。
海汼部落原创文章,原文链接:()