2.泛型类
3.泛型函数
4.上边界Bounds,下边界Bounds
5.View Bounds 限定类
6.Context Bounds
7.Manifest Context Bounds
8.scala中的 协变,逆变
9.Existential Type
1.何为泛型
定义:“参数化类型”
顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,
此时类型也定义成参数形式(可以称之为类型形参)
然后在使用/调用时传入具体的类型(类型实参)。
作用:
限定(类,函数)中 参数类型,实现程序更好的健壮性
例子:
List a = new ArrayList[Integer]()
List a = new ArrayList()
a.add(1)
a.add("2")
判断:a.get(1) == 2 ,不加限定,那么就会报错
2.泛型类
含义:类的声明中,定义一些泛型类型,然后在类内部
比如field或者method,就可以使用这些泛型类型
作用:让使用了T定义的 field,method,类型保持一致
特点:自动推断类型的能力
在创建类时,不用主动限定T,会依据你传入的参数进行判断
结构:
class Student[T](val v:T){}
var student = new Student[T](T);
例子:
class Student[T,V](val localId: T,val localId2:V) {
def getSchoolId(hukouId: T,hukouId2:V) = "S-" + hukouId + "-" + hukouId2+"-"localId+"-"+localId2
}
val leo = new Student[Int,String](111,"222")
leo.getSchoolId(222,"222")
3.泛型函数
含义:泛型类一样,在scala中同属于一等公民
结构:
def getCard[T](v:T)={}
例子:
def getCard[T](content: T) = {
if(content.isInstanceOf[Int]) "card: 001, " + content
else if(content.isInstanceOf[String]) "card: this is your card, " + content
else "card: " + content
}
getCard[String]("hello world")
4.上边界Bounds,下边界Bounds
含义:
(1)边界:限定于有父子关系的两个类
(2)上,下:限定于 该类型,或者该类型的子类,或者父类(包含关系)
适用范围:限定方法,限定类均可
例子:在派对上交朋友
class Person(val name: String) {
def sayHello = println("Hello, I'm " + name)
def makeFriends(p: Person) {
sayHello
p.sayHello
}
}
class Student(name: String) extends Person(name)
class Party[T <: Person](p1: T, p2: T) {
def play = p1.makeFriends(p2)
}
def getCard[T<:Person](content: T,content2:T) = {
println(content.makeFriends(content2))
}
例子:领身份证
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.")
}
5.View Bounds 限定类
含义: 相当于父子类的加强版
(1)支持有父子关系的多种类型
(2)支持“被隐式转换后”的类型判断
结构:
class Party[T <% Person](p1: T, p2: T)
比较:冒号“:” 替换为 百分号 “%”
例子:跟小狗交朋友
class Person(val name: String) {
def sayHello = println("Hello, I'm " + name)
def makeFriends(p: Person) {
sayHello
p.sayHello
}
}
class Student(name: String) extends Person(name)
class Dog(val name: String) { def sayHello = println("Wang, Wang, I'm " + name) }
implicit def dog2person(dog: Object): Person = if(dog.isInstanceOf[Dog]) {val _dog = dog.asInstanceOf[Dog]; new Person(_dog.name) } else Nil
class Party[T <% Person](p1: T, p2: T) {
def play = p1.makeFriends(p2)
}
var leo = new Student("leo")
var dog = new Dog("wangcai")
var party = new Party(leo,dog)
party.play
执行结果比较慢
6.Context Bounds
含义: scala使用到上下文中的隐式值以及注入
特点:更加接洽与scala内置类的应用于比较
结构:
class Calculator[T: Ordering] (val number1: T, val number2: T) {
def max(implicit order: Ordering[T]) = 方法块儿(order.compare(number,number2))
}
例子:
class Calculator[T: Ordering] (val number1: T, val number2: T) {
def max(implicit order: Ordering[T]) = if(order.compare(number1, number2) > 0) number1 else number2
}
var cal = new Calculator(1,24)
cal.max // 即可比较大小
7.Manifest Context Bounds
含义:实例化一个泛型数组,就必须使用Manifest Context Bounds
特点:针对于数组,集合而言(前面是针对单个对象)
例子:
class Meat(val name: String)
class Vegetable(val name: String)
def packageFood[T: Manifest] (food: T*) = {
val foodPackage = new Array[T](food.length)
for(i <- 0 until food.length) foodPackage(i) = food(i)
foodPackage
}
val v1 = new Vegetable("tudou")
val v2 = new Vegetable("doufu")
val packageFood = packageFood(v1,v2)
8.scala中的 协变,逆变
含义:scala依据对象中传递的参数来协从的判断对象之间的从属关系
例子:Java中,如果有Professional是Master的子类,那么Card[Professionnal]是不是Card[Master]的子类
特点:更加灵活,直接用父子类,来对别的类的对象们进行了上下关系的区分
结构:
class Card[+T]()
class Card[-T]()
+ 表示T和T的子类
- 表示T和T的父类
例子:
class Master
class Professional extends Master
// 大师以及大师级别以下的名片都可以进入会场
class Card[+T] (val name: String)
def enterMeet(card: Card[Master]) {
println("welcome to have this meeting!")
}
val card1 = new Card[Master]("Tom")
val card2 = new Card[Professional]("Leo")
enterMeet(card1) OK
enterMeet(card2) OK
例子2:
class Master
class Professional extends Master
class Card[-T] (val name: String)
def enterMeet(card: Card[Master]) {
println("welcome to have this meeting!")
}
val card1 = new Card[Master]("Tom")
val card2 = new Card[Professional]("Leo")
enterMeet(card1) OK
enterMeet(card2) No
9.Existential Type
特点:特殊的类型占位符,表示在声明时,必须限定某一个类型
例子:
Array[_] = Array[T] forSome { type T }