类或特质可以定义一个在子类中被具体化的抽象类型,如下:
trait Reader {
type Contents //这里定义一个抽象类型,子类中必须指定这个类型
def read(fileName: String): Contents
}
class StringReader extends Reader {
type Contents = String
def read(fileName: String) =Source.fromFile(fileName, "UTF-8").mkString
}
class ImageReader extends Reader {
type Contents = BufferedImage
def read(fileName: String) =ImageIO.read(new File(fileName))
}
//上面的抽象类型也可以写为下面的这种形式 这种方式是 类型参数
trait ReaderC[C] {
def read(fileName: String): C
}
抽象类型还可以使用界定,与类型参数一样
trait Listener {
type Event <: java.util.EventObject
}
这样在子类中指定的时候EVENT必须是EventObject的一个兼容的类型
package demo
/**
* @author Administrator
*/
object ScalaType {
object show
object then
object around
def main(args: Array[String]): Unit = {
// val bug = new Bug()
// bug move 4 and show and then move 6 and show turn around move 5 and show
printValues((x: Int) => x * x, 3, 6)
printValues(Array(1, 1, 2, 3, 5, 8, 13, 21,34, 55), 3, 6)
}
class Bug {
var direction: Boolean = true
var postion: Int = 0
def move(step: Int) = {
val tmp = if (direction) step else -step
postion += tmp
this
}
def turn(): this.type = {
direction = !direction
this
}
// def show = {
// print(postion + " ")
// this
// }
def and(obj: show.type) = { print(postion +" "); this }
def and(obj: then.type) = this
def turn(obj: around.type): this.type =turn()
}
def fun(obj: { def close(): Unit }, f: { defclose(): Unit } => Unit) {
try {
f(obj)
} catch {
case e: Exception => obj.close();e.printStackTrace()
} finally {
obj.close()
}
}
def printValues(f: { def apply(v: Int): Int}, from: Int, to: Int) {
for (i <- from to to)println(f.apply(i))
}
abstract class Dim[T](val value: Double, valname: String) {
this: T =>
protected def create(v: Double): T
def +(other: Dim[T]) = create(value +other.value)
override def toString() = value + "" + name
}
class Seconds(v: Double) extendsDim[Seconds](v, "s") {
override def create(v: Double) = newSeconds(v)
}
class Meters(v: Double) extendsDim[Meters](v, "m") {
override def create(v: Double) = newMeters(v)
}
}