泛型
- 泛型类

1 package day0603 2 3 class GenericClassInt { 4 private var content:Int=10 5 def set(value:Int)={content=value} 6 def get():Int={content} 7 } 8 9 class GenericClassString { 10 private var content:String="" 11 def set(value:String)={content=value} 12 def get():String={content} 13 } 14 15 class GenericClass[T]{ 16 private var content:T = _ 17 def set(value:T) = {content=value} 18 def get():T={content} 19 } 20 21 object GenericClass{ 22 def main(args: Array[String]):Unit = { 23 var v1 = new GenericClass[Int] 24 v1.set(1000) 25 v1.get() 26 27 var v2 = new GenericClass[String] 28 v2.set("Hello") 29 v2.get() 30 } 31 }
- 泛型函数
- ClassTag表示Scala在运行时的状态信息,这里表示调用时的数据类型
- 上界和下界
- 规定泛型的取值范围
- 上界:S <: T 规定了S的类型必须是T的子类或者本身
- 下界:U >: T 规定了U的类型必须是T的父类或者本身

1 package day0603 2 3 class Vehicle{ 4 def drive()={println("Driving")} 5 } 6 7 class Car extends Vehicle{ 8 override def drive()={println("Car Driving")} 9 } 10 11 class Bike extends Vehicle{ 12 override def drive()={println("Bike Driving")} 13 } 14 15 object ScalaUpperBound { 16 def takeVehicle[T <: Vehicle](v:T)={v.drive()} 17 def main(args: Array[String]):Unit = { 18 19 var v:Vehicle = new Vehicle 20 takeVehicle(v) 21 22 var c:Vehicle = new Car 23 takeVehicle(c) 24 25 //不能传递别的类型 26 //takeVehicle("Hello") 27 } 28 }
- 视图界定(View Bound)
- 除了可以接收上界和下界规定的类型以外,还可以接收能够通过隐式转换过去的其他类型,用 % 表示
- 首先调用int2String,把Int转为String,再调用addTwoString
- 协变和逆变
- 协变:在类型参数的前面加 +,泛型变量的值可以是本身类型或其子类类型

1 package day0603.demo1 2 3 class Animal 4 5 class Bird extends Animal 6 class Sparrow extends Bird 7 8 class EatSomething[+T](t:T) 9 10 object DemoClass1 { 11 def main(args: Array[String]):Unit = { 12 var c1:EatSomething[Bird] = new EatSomething[Bird](new Bird) 13 //尽管Bird是Animal的这子类,但EatSometing[Bird]不是EatSometing[Animal]的子类 14 var c2:EatSomething[Animal] = c1 15 16 var c3:EatSomething[Sparrow]=new EatSomething[Sparrow](new Sparrow) 17 var c4:EatSomething[Animal]=c3 18 } 19 }
-
- 逆变:在类型参数的前面加 -,泛型变量的值可以是本身类型或其父类类型

1 package day0603.demo2 2 3 class Animal 4 5 class Bird extends Animal 6 class Sparrow extends Bird 7 8 class EatSomething[-T](t:T) 9 10 object Demo2Class { 11 def main(args: Array[String]):Unit = { 12 var c1:EatSomething[Bird] = new EatSomething[Bird](new Bird) 13 //var c2:EatSomething[Sparrow] = new EatSomething[Sparrow](new Sparrow) 14 //尽管Bird是Sparrow的父类,但EatSometing[Bird]不是EatSometing[Sparrow]的父类 15 var c2:EatSomething[Sparrow] = c1 16 } 17 }
隐式转换
- 隐式转换函数
- 多了一个关键字implicit
- 定义后,不需要显示调用,编译器会自动调用

1 package day0603 2 3 class Fruit(name:String){ 4 def getFruitName():String=name 5 } 6 7 class Monkey(f:Fruit){ 8 def say()={println("Monkey like "+f.getFruitName())} 9 } 10 11 object ImplicitDemo { 12 13 implicit def fruit2Monkey(f:Fruit):Monkey = {new Monkey(f)} 14 15 def main(args: Array[String]):Unit = { 16 var f:Fruit = new Fruit("Banana") 17 18 //把Fruit转成Monkey就可调用say() 19 f.say() 20 } 21 }
Monkey like Banana
- 隐式参数
- 调用时没有给函数传递参数值,采用隐式参数
- 隐式类
- 可增强类的功能

1 object ImplicitClassDemo { 2 //定义隐式类,增强对象功能 3 implicit class Calc(x:Int){ 4 def add(y:Int):Int = x+y 5 } 6 7 def main(args: Array[String]):Unit = { 8 println("两个数字的和是: " + 1.add(2)) // 没有add方法 9 } 10 }
两个数字的和是: 3