[Scala] 高级特性

泛型

  • 泛型类
 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 }
View Code
  • 泛型函数
    • 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 Code

  • 视图界定(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 }
View Code
    • 逆变:在类型参数的前面加 -,泛型变量的值可以是本身类型或其父类类型
 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 }
View Code

隐式转换

  • 隐式转换函数
    • 多了一个关键字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 }
View Code

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 }
View Code

两个数字的和是: 3

原文地址:https://www.cnblogs.com/cxc1357/p/13034830.html