面向对象来看,接口并不属于面向对象的范畴,Scala是纯面向对象的语言,在Scala中,没有接口。Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。理解trait等价于(interface+abstract class)。
1.trait的声明
trait 特质名 {
trait 体
}
特质名 一般首字母大写 Cloneable,Serializable。
在Scala中,Java中的接口可以当做特质使用。
object boke_demo01 {
def main(args: Array[String]): Unit = {
}
}
//trait Serializable extends Any with java.io.Serializable
//在scala中,java的接口都可以当做trait来使用(如上面的语法)
object T1 extends Serializable {
}
object T2 extends Cloneable {
}
一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了extends关键字,如果有多个特质或存在父类,那么需要采用with关键字连接。
没有父类:
class 类名 extends 特质1 with 特质2 with 特质3…
有父类:
class 类名 extends 父类 with 特质1 with 特质2 with 特质3…
2.trait的引入
引入trait特质,第一可以替代Java的接口,第二也是对单继承机制的一种补充
object boke_demo01 {
def main(args: Array[String]): Unit = {
val c = new C()
val f = new F()
c.getConnect() // 连接mysql数据库...
f.getConnect() // 连接oracle数据库..
}
}
//按照要求定义一个trait
trait Trait {
//定义一个规范
def getConnect()
}
//先将六个类的关系写出
class A {}
class B extends A {}
class C extends A with Trait {
override def getConnect(): Unit = {
println("连接mysql数据库...")
}
}
class D {}
class E extends D {}
class F extends D with Trait {
override def getConnect(): Unit = {
println("连接oracle数据库..")
}
}
特质可以同时拥有抽象方法和具体方法,一个类可以实现/继承多个特质。
object boke_demo01 {
def main(args: Array[String]): Unit = {
//创建sheep
val sheep = new Sheep
sheep.sayHi()
sheep.sayHello()
}
}
//当一个trait有抽象方法和非抽象方法时
//1. 一个trait在底层对应两个 Trait.class 接口
//2. 还对应 Trait$class.class Trait$class抽象类
trait Trait {
//抽象方法
def sayHi()
//实现普通方法
def sayHello(): Unit = {
println("say Hello~~")
}
}
//当trait有接口和抽象类是
//1.class Sheep extends Trait 在底层 对应
//2.class Sheep implements Trait
//3.当在 Sheep 类中要使用 Trait的实现的方法,就通过 Trait$class
class Sheep extends Trait {
override def sayHi(): Unit = {
println("小羊say hi~~")
}
}
类通过extends继承特质,通过with关键字可以继承多个特质。
所有的Java接口都可以当做Scala特质使用。
3.动态混入特质的对象
在构建对象时混入特质,扩展目标类的功能。动态混入是Scala特有的方式(Java没有动态混入),可在不修改类声明/定义的情况下,扩展类的功能。动态混入可以在不影响原有的继承关系的基础上,给指定的类扩展功能。
object boke_demo01 {
def main(args: Array[String]): Unit = {
//在不修改类的定义基础,让它们可以使用trait方法
val oracleDB = new OracleDB with Operate
oracleDB.insert(100) //
val mySQL = new MySQL with Operate
mySQL.insert(200)
//如果一个抽象类有抽象方法,如何动态混入特质
val mySql_ = new MySQL_ with Operate {
override def say(): Unit = {
println("say")
}
}
mySql_.insert(999)
mySql_.say()
}
}
trait Operate { //特质
def insert(id: Int): Unit = { //方法(实现)
println("插入数据 = " + id)
}
}
class OracleDB { //空
}
abstract class MySQL { //空
}
abstract class MySQL_ { //空
def say()
}
在Scala中创建对象的4种方式:new 对象、apply 创建、匿名子类方式、动态混入。
————Blueicex 2020/2/18 20:46 blueice1980@126.com