Trait的定义及使用
Trait的设计及功能
- Trait的设计类似于Java中Interface的设计,可以当做Java中的Interface来使用,但是比接口的功能更加强大
- 当Trait当做Interface来使用时,基本与Interface没有区别
Trait的定义语法
-
关键字:trait
-
定义
trait HelloTrait { //抽象方法 def sayHello } trait ByeTrait { def sayBye }
Trait的使用
-
关键字:extends
- Scala中类的继承和Trait的实现都使用extends来表示
-
实现多个关键字:with
class Person06 extends HelloTrait with ByeTrait with Serializable { //实现接口中的抽象方法 override def sayHello: Unit = println("Hello ~ Person") override def sayBye: Unit = println("Bye ~ Person") } object Person06{ def main(args: Array[String]): Unit = { val p1 = new Person06 p1.sayHello p1.sayBye } }
Trait实现工具类的封装
Trait中的方法定义
- 抽象方法:只定义方法名,没有方法体,没有实现逻辑
- 具体方法:定义了方法名和方法体,包含了实现逻辑
- Trait中既可以定义抽象方法,也可以定义具体方法
Trait实现封装工具类
-
在Trait中定义具体的方法,所有继承了该Trait的类都具有了该方法
- 构建一个工具类的父类:包含通用的工具方法
-
TimeUtils:时间字符串的剪切和拼接
-
URLUtils:剪切和拼接url
-
需求:构建一个Trait,实现切分字符串和拼接字符串
-
测试
trait StringUtilsTrait { //可以定义抽象方法和属性,当做接口来实现 //可以定义具体的方法和属性 def subStr(str:String,start:Int,len:Int):String = { str.substring(start,start+len) } def concatStr(sep:String,str:String *):String = { str.mkString(sep) } } object TimeUtils extends StringUtilsTrait {} object URLUtils extends StringUtilsTrait{} object TestTrait{ def main(args: Array[String]): Unit = { val str1 = "I" val str2 = "like" val str3 = "learning" println(TimeUtils.subStr(str3,0,5)) println(TimeUtils.concatStr("-",str1,str2,str3)) } }
-
实例混入Trait
实例混入Trait的介绍
- 实例混入Trait指的是为了解决相同类的不同实例继承不同Trait的问题
- 在构建同一个类的实例时,可以指定当前实例化的对象继承哪些Trait
实例混入Trait的语法
val 对象名称 = new 类 with Trait1 with Trait2 ……
实例混入Trait的实现
-
实例混入Trait指的是为了解决相同类的不同实例继承不同Trait的问题
-
在构建同一个类的实例时,可以指定当前实例化的对象继承哪些Trait
-
正常的trait的继承:定义类的实现继承
class Person extends Trait class Person01 extends HelloTrait { override def sayHello: Unit = println("Hello Person") } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 p1.sayHello val p2 = new Person01 p2.sayHello } }
-
实例混入trait:指的是可以在构建对象的时候来实现继承Trait
实例混入Trait的语法
val 对象名称 = new 类 with Trait1 with Trait2 ……
实例混入Trait的实现
-
需求1:对象1能sayHello,对象2不能
class Person01 {
}
object TestPerson01{
def main(args: Array[String]): Unit = {
val p1 = new Person01 with HelloTrait {
override def sayHello: Unit = println("Hello")
}
p1.sayHello
val p2 = new Person01
p2.sayHello //报错
}
}
```
-
需求2:对象1能sayHello,对象2能sayBye
class Person01 { } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 with HelloTrait { override def sayHello: Unit = println("Hello") } p1.sayHello val p2 = new Person01 with ByeTrait { override def sayBye: Unit = println("Bye") } p2.sayBye } }
-
需求3:对象1能sayHello,对象1和对象2都能sayBye,对象2能拼接字符串
class Person01 { } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 with HelloTrait with ByeTrait { override def sayHello: Unit = println("Hello") override def sayBye: Unit = println("Bye") } p1.sayHello p1.sayBye val p2 = new Person01 with ByeTrait with StringUtilsTrait { override def sayBye: Unit = println("Bye") } p2.sayBye p2.concatStr("-","I","like") } } class Person01 extends ByeTrait { override def sayBye: Unit = println("Bye") } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 with HelloTrait { override def sayHello: Unit = println("Hello") } p1.sayHello p1.sayBye val p2 = new Person01 with StringUtilsTrait p2.sayBye p2.concatStr("-","I","like") } }
Trait的构造机制及Trait继承Class
- **Trait的构造器**
-
Trait不支持构造参数,但是每个Trait都有一个无参构造器
-
类中:除了成员属性和成员方法外,其他的所有代码都属于主构造器
class Person02(var name:String,var age:Int) { println("Start ……………………") //成员属性 var country :String = "China" //成员方法 def sayHello = println("Hello") println("End ……………………") } object Person02{ def main(args: Array[String]): Unit = { val itcast = new Person02("itcast",18) itcast.sayHello } }
类的基本构造顺序
-
从左到右依次执行继承的父类或者Trait的构造,再执行自身的构造
-
继承一个类
class Person02() { println("Start Person ……………………") println("End Person ……………………") } class Student02 extends Person02{ println("Start Student ……………………") println("End Student ……………………") } object Person02{ def main(args: Array[String]): Unit = { val student = new Student02 } }
-
继承一个类和两个Trait
class Person02() { println("Start Person ……………………") } trait HelloTrait1 { println("Start HelloTrait ……") } trait ByeTrait1 { println("Start ByeTrait ……") } class Student02 extends Person02 with HelloTrait1 with ByeTrait1 { println("Start Student ……………………") } object Person02{ def main(args: Array[String]): Unit = { val student = new Student02 } }
复杂继承的构造顺序
-
如果一个类继承多个Trait,而Trait又继承父Trait,先构造父Trait,再构造子Trait
-
如果多个子Trait的父Trait相同,则父Trait只构造一次
-
继承关系
```scala
class Student extends Person with MyLogger with TimeLogger
Trait MyLogger extends Logger
Trait TimeLogger extends Logger
```
-
构造顺序
class Person02() { println("Start Person ……………………") } trait Logger{ println("Strat Logger ……") } trait MyLogger extends Logger { println("Start MyLogger ……") } trait TimeLogger extends Logger { println("Start TimeLogger ……") } class Student02 extends Person02 with MyLogger with TimeLogger { println("Start Student ……………………") } object Person02{ def main(args: Array[String]): Unit = { val student = new Student02 } }
Trait继承Class的实现
-
class extends Trait:类继承Trait
-
trait extends Class:Trait继承类
class Person03 { def sayWhat = println("I like leanring") } trait PersonTrait extends Person03{ def sayBye } class Student extends PersonTrait{ override def sayBye: Unit = println("bye") } object Stduent{ def main(args: Array[String]): Unit = { val student = new Student student.sayBye student.sayWhat } }
- 如果一个类的实例调用了一个方法
- 这个方法不在这个类中,也不在实现的接口中,可能在接口的父类中
点个赞嘛!