本文部分参考自:https://blog.csdn.net/dataiyangu/article/details/98483033
Scala第七天——面向对象编程
自己的话:漆黑的黑夜 表示着威胁 我选择诙谐
工作在堆叠 没兑现归结于那些理解
Scala特质
一、不允许多重继承
Scala 和 Java 都不允许多重继承,多继承会出现菱形继承问题,Scala 提 供了特质,类似于 Java 中的接口,特质可以同时拥有抽象方法和具体方法, 一个类可以实现多个特质。
如图一个父类被两个子类继承,然后两个子类都重写了父类的方法,这个时候又有一个子类同时继承了上面中间的两个子类,这个时候就会出现问题,相当于最上面的父类在类中有两个,这可能不是我们想要的结果,增加调用的困难,同时也会浪费内存资源。
二、将trait作为接口使用
1.简述:
(1)Scala中的Triat可以不是只定义抽象方法,还可以定义具体方法,此时trait更像是包含了通用工具方法的东西
(2)有一个专有的名词来形容这种情况,就是说trait的功能混入了类
举例来说,trait中可以包含一些很多类都通用的功能方法,比如打印日志等等,spark中就使用了trait来定义了通用的日志打印方法
trait Logger {
def log(message: String) = println(message)
}
class Person(val name: String) extends Logger {
def makeFriends(p: Person) {
println("Hi, I'm " + name + ", I'm glad to make friends with you, " + p.name)
//log调用继承接口的方法
log("makeFriends methdo is invoked with parameter Person[name=" + p.name + "]")
}
}
2.详解:
trait Logger {
def log(msg: String) // An abstract method
}
class ConsoleLogger extends Logger // Use extends, not implements
with Cloneable with Serializable {
// Use with to add multiple traits def
log(msg: String) {
println(msg) } // No override needed
}
特质中没有实现的方法就是抽象方法。
类通过 extends 继承特质,通过 with 可以继承多个特质。
Logger with Cloneable with Serializable 是一个整体,extends 这个整体 所有的 java 接口都可以当做 Scala 特质使用。
三、在Trait中定义具体方法
** 带有具体实现的特质:**
特质中的方法并不一定是抽象的,也可以有具体实现比如
trait
ConsoleLogger {
def log(msg: String) {
println(msg) }
}
class Account {
protected var balance = 0.0
}
class SavingsAccount extends Account with ConsoleLogger {
def withdraw(amount: Double) {
if (amount > balance) log("Insufficient funds")
else balance -= amount
}
// More methods ...
}
使 SavingsAccount 得到了一个具体的 log 方法(minix)混入, 并不是通过继承得来。
四、在Trait中定义具体字段
1.简述:
(1)Scala中的Triat可以定义具体field,此时继承trait的类就自动获得了trait中定义的field
(2)但是这种获取field的方式与继承class是不同的:如果是继承class获取的field,实际是定义在父类中的;而继承trait获取的field,就直接被添加到了类中
trait Person {
val eyeNum: Int = 2
}
class Student(val name: String) extends Person {
def sayHello = println("Hi, I'm " + name + ", I have " + eyeNum + " eyes.")
}
2.详解:
特质中可以定义具体字段,如果初始化了就是具体字段,如果不初始化 就是抽象字段。
混入该特质的类就具有了该字段,字段不是继承,而是简单的加入类。 是自己的字段
trait
Logger {
def log(msg: String)
}
trait ConsoleLogger extends Logger {
def log(msg: String) {
println(msg) }
}
trait ShortLogger extends Logger {
val maxLength = 15
abstract override def log(msg