泛型
泛型类
class GenericClass[T] {
private var content:T = _
def set(value:T) = {content = value}
def get():T= {content}
}
object GenericClass{
def main(arg: Array[String]): Unit = {
var intGeneric = new GenericClass[Int]
intGeneric.set(123)
println(intGeneric.get())
var stringGeneric = new GenericClass[String]
stringGeneric.set("hello scala")
println(stringGeneric.get())
}
}
泛型函数
- 在泛型函数中,
T
必须是ClassTag
类型 ClassTag
表示执行Scala程序时的运行信息;在下例中,表示数据的类型
import scala.reflect.ClassTag
def mkArray[T:ClassTag](elems:T*) = Array[T](elems:_*)
mkArray(1,2,3)
mkArray('a','b','c')
上界、下界
- 规定泛型的取值范围
- 假设继承关系:(父)A —> B —> C —> D(子),则,
D <: y泛型 <: B
表示,y的类型只能是B、C、D - 定义:
- 上界:
S <: T
,表示S的类型必须是T的子类 - 下界:
U >: T
,表示U的类型必须是T的父类
class Vehicle{
def drive() = {println("Driving")}
}
class Car extends Vehicle{
override def drive(): Unit = {println("Car Driving")}
}
class Bike extends Vehicle{
override def drive(): Unit = {println("Bike Driving")}
}
class Apple
object ScalaUpperBound{
def takeVehicle[T <: Vehicle(v:T)] = {v.drive()}
def main(args: Array[String]): Unit = {
var v1:Vehicle = new Vehicle
var v2:Car = new Car
var v3:Apple = new Apple
takeVehicle(v1)
takeVehicle(v2)
takeVehicle(v3)
}
}
视图界定
- 上下界的扩展,适用范围更广泛
- 以上界为例
<:
- 除了接收所有的子类,还允许接受隐式转换过去的类型
- 需要定义转化规则(隐式转换函数)
def addTwoString[T <: String](x:T, y:T) = {println(x + y)}
addTwoString("hello", "world")
addTwoString(100, 200)
implicit def int2String(n:Int):String = {n.toString}
def addTwoString[T <% String](x:T, y:T) = {println(x + y)}
addTwoString("hello", "world")
addTwoString(100, 200)
协变和逆变
- 可以看作是视图界定的一个扩展
- 缺点:降低了代码的可读性
- 协变:若一个泛型类接受的泛型参数可以是本身的类型或子类的类型
class Animal
class Bird extends Animal
class Sparrow extends Bird
class EatSomething[+T](t:T){}
object Demo{
def main(args: Array[String]): Unit = {
var c1:EatSomething[Bird] = new EatSomething[Bird](new Bird)
var c2:EatSomething[Animal] = c1
var c3:EatSomething[Sparrow] = new EatSomething[Sparrow](new Sparrow)
var c4:EatSomething[Animal] = c3
}
}
- 逆变:若一个泛型类接受的泛型参数可以是本身的类型或父类的类型
class Animal
class Bird extends Animal
class Sparrow extends Bird
class EatSomething[-T](t:T){}
object Demo2{
def main(args: Array[String]): Unit = {
var c1:EatSomething[Bird] = new EatSomething[Bird](new Bird)
var c2:EatSomething[Sparrow] = c1
}
}
隐式转换函数
class Fruit(name:String){
def getFruitName():String = {name}
}
class Monkey(f:Fruit){
def say() = {println("Monkey like " + f.getFruitName())}
}
object ImplicitDemo{
implicit def fruit2Monkey(f:Fruit): Monkey = {new Monkey(f)}
def main(args: Array[String]): Unit = {
var f:Fruit = new Fruit("香蕉")
f.say()
}
}
隐式参数
def testParam(implicit name:String) = {println("The value is " + name)}
implicit val name:String = "这是一个隐式参数"
testParam
隐式类
- class前加
implicit
- 作用:对类的功能进行加强
object ImplicitDemo2{
implicit class Calculate(x:Int){
def add(y:Int) = x + y
}
def main(args: Array[String]): Unit = {
println(1.add(2))
}
}