内部类
scala
的内部类和Java
存在差异。像Java
这种语言,内部类很多时候就是为了区分命名上的差异;而scala
中,却完全表示两种对象。举个例子:
package example
class AppleBasket {
case class Apple(name: String, price: Float)
private var apples: List[Apple] = Nil
def addApple(apple: Apple) = apples = apple :: apples
}
object MyExample {
def main(args: Array[String]): Unit = {
val ab0 = new AppleBasket
val ab1 = new AppleBasket
val a0 = new ab0.Apple("a0", 1.1f)
ab0.addApple(a0)
// 这里直接报错,只有ab0才能添加a0
// ab1.addApple(a0)
}
}
对象的内部类是不能混合的。
抽象类型
直接给出代码实例,注意type
的使用方式:
package example
abstract class Buffer[+T] {
val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
def length = element.length
}
object MyExample {
def newIntSeqBuffer(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = {
new SeqBuffer[Int, Seq[Int]] {
val element = List(e1, e2)
}
}
def main(args: Array[String]): Unit = {
val buf = newIntSeqBuffer(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
}
}
复合类型
有时需要表明一个对象的类型是其他几种类型的子类型。举个例子:
package example
trait Fly {
def fly(): Unit
}
trait Run {
def run(): Unit
}
class Bird extends Fly with Run {
override def fly() = println("Bird fly")
override def run() = println("Bird run")
}
object MyExample {
// 注意这里的with,表示复合类型
def op(action: Fly with Run) {
action.fly()
action.run()
}
def main(args: Array[String]): Unit = {
val bird = new Bird
op(bird)
}
}
代码输出:
Bird fly
Bird run
自类型
自类型用于声明一个特质必须混入其他特质,尽管该特质没有直接扩展其他特质。举个例子:
package example
trait Fly {
val wingName: String
def fly(): Unit
}
trait Run {
this: Fly => // 自类型,这里表示可以使用Fly的特性了
def showWingName() = println(s"My wing is $wingName")
def run(): Unit
}
class Bird extends Fly with Run {
override val wingName: String = "Bird-Wing"
override def fly(): Unit = println("Bird fly")
override def run(): Unit = println("Bird run")
}
object MyExample {
def main(args: Array[String]): Unit = {
val bird = new Bird
bird.showWingName()
}
}