scala泛型(二十二)

简介

  scala中可以使用泛型来修饰类、特质和函数,这样的类、特质和函数可用于操作多种类型数据。比如,Array[T]可以存放指定类型T的数据。

泛型修饰的类

class Animals[A,B](var name: A, var age: B) {
    println(s"Name is $name, Age is $age")
}

object GenericClient extends App {
    val cat = new Animals[String,Int]("小花",2)
    val dog = new Animals[String,String]("阿黄","5")
}

泛型修饰的函数

def asList[T](pSrc:Array[T]): List[T] = {
    if (pSrc == null || pSrc.isEmpty) {
        List[T]()
    } else {
        pSrc.toList
    }
}
val friends = Array("小白","琪琪","乐乐")
val friendList = cat.asList(friends)
println(friendList.isInstanceOf[List[String]])

泛型界定

上边界

class Pair[T <: Comparable[T]](val first:T, val second:T) {
    def smaller = {
        if (first.compareTo(second) < 0) {
            println("first < second")
        } else if (first.compareTo(second) > 0) {
            println("first > second")
        } else {
            println("first = second")
        }
    }
}
val p = new Pair[String]("10","20")
p.smaller

下边界

class Father(val name: String)
class Child(name: String) extends Father(name)
def getIDCard[R >: Child](person:R) {
    if (person.getClass == classOf[Child]) {
        println("please tell us your parents' names.")
    } else if (person.getClass == classOf[Father]) {
        println("sign your name for your child's id card.")
    } else {
        println("sorry, you are not allowed to get id card.")
    }
}

val c = new Child("ALice")
getIDCard(c)

视图边界

  class Pair[T<: Comprable[T]],如果尝试new Pair[2,3],肯定会报错,提示Int不是Comparable[Int]的子类。

  Scala Int类型没有实现Comparable接口,(注意Java的包装类型是可以的),但是RichInt实现了Comparable[Int],同时还有一个Int到RichInt的隐式转换,这里就可以使用视图界定。

  视图边界使用一个可用的隐式转换函数将一种类型自动转换为另外一种类型,定义如下:
def funcA <% B = 函数体
等价于def funcA (implicit m:A=>B) = 函数体

class Person(val name: String) {
    def sayHello = println("Hello, I'm " + name)
    def makeFriends(p: Person) {
        sayHello
        p.sayHello
    }
}

class Dog(val name: String) {
    def sayHello = println("汪汪, I'm " + name)
    implicit def dog2person(dog: Object): Person = {
        if(dog.isInstanceOf[Dog]) {
            val _dog = dog.asInstanceOf[Dog];
            new Person(_dog.name);
        } else {
            null
        }
    }
}

class Party[T <% Person](p1:T,p2:T)

class Pairs[T <% Ordered[T]] (val first:T, val second:T) {
    def smaller = if (first < second) first else second
}

上下文边界

  视图边界: T <% V必须要求存在一个T 到V的隐式转换。而上下文界定的形式就是[T:M],其中M是另一个泛型类,要求必须存在一个类型为M[T]的隐式值。

  def funcT:S = 函数体,表示这个函数参数p的类型是T,但是在调用函数func的时候,必须有一个隐式值S[T]存在,也可以这样写:
def funcT(implicit arg:S[T]) = 函数体

class Fraction[T:Ordering](val a:T, val b:T) {
    def small(implicit order:Ordering[T]) = {
        if (order.compare(a,b) < 0) println(a.toString) else println(b.toString)
    }
}

class ModelOrdering extends Ordering[Model]{
    override def compare(x: Model, y: Model): Int = {
        if (x.name == y.name) {
            x.age - y.age
        } else if (x.name > y.name) {
            1
        } else {
            -1
        }
    }
}


object ImplicitClient extends App {
    //编译器需要能够找到这个隐式值。这个隐式值可以是变量也可以是函数。
    //implicit valmo = new ModelOrdering
    implicit def mo = new ModelOrdering

    val f = new Fraction(new Model("Shelly",28),new Model("Alice",35))
    f.small
}

忠于技术,热爱分享。欢迎关注公众号:java大数据编程,了解更多技术内容。

这里写图片描述

你可能感兴趣的:(scala,scala,泛型,上边界,下边界,视图边界)