匿名内部类
匿名内部类的本质
- 一个没有名字的类,自动构建一个类继承抽象类或者接口,实现可以new一个抽象类或者接口
匿名内部类的定义语法
val 变量名称 = new 抽象类/Trait{
//重写属性或者方法
}
直接new一个抽象类或者Trait的子类,重写方法后将对象赋值给一个变量
匿名内部类的实现
abstract class Person05 {
//具体的属性
// var name:String = "itcast"
// var age:Int = 20
//抽象的属性
var name:String
var age:Int
//具体的方法
// def sayHello = println("Hello,Person ~")
//抽象的方法
def sayHello
}
//如果多次构建这个类的实例
class Stduent05 extends Person05 {
override var name: String = "student"
override var age: Int = 18
override def sayHello: Unit = println("Hello,Student ~")
}
object TestStudent05{
def main(args: Array[String]): Unit = {
//正常通过构建子类的实例,来实现对抽象类的使用
val student = new Stduent05
student.sayHello
//通过匿名内部类实现new 抽象类:一般用于临时的使用一次抽象类或者接口的方法
val person = new Person05 {
override var name: String = "heima"
override var age: Int = 10
override def sayHello: Unit = println("Hello, Person ~")
}
person.sayHello
}
}
Trait
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的类都具有了该方法
- 构建一个工具类的父类:包含通用的工具方法
-
实现
//需求:构建一个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的继承:定义类的实现继承
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 Logger {
def log(msg:String) = println(msg)
}
class UserService
def main(args: Array[String]): Unit = {
val service = new UserService with Logger
service.log("混入的方法")
}
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的构造,再执行自身的构造
继承一个类和两个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
}
}
//输出结果
Start Person ……………………
Start HelloTrait ……
Start ByeTrait ……
Start Student ……………………
复杂继承的构造顺序
-
如果一个类继承多个Trait,而Trait又继承父Trait,先构造父Trait,再构造子Trait
-
如果多个子Trait的父Trait相同,则父Trait只构造一次
-
继承关系
class Student extends Person with MyLogger with TimeLogger1 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
}
}
//输出结果
Start Person ……………………
Strat Logger ……
Start MyLogger ……
Start TimeLogger ……
Start Student ……………………
小结:
- 基本:从左往右依次构造,最后构造自己
- 特殊:如果继承的Trait有父Trait,先构造父Trait,再构造子Trait
- 如果子Trait的父Trait是同一个,父Trait只构造一次