scala之类型参数

版权声明: https://blog.csdn.net/weixin_39966065/article/details/89944018

 

目录

 

1.何为泛型

2.泛型类

3.泛型函数

4.上边界Bounds,下边界Bounds

5.View Bounds 限定类

6.Context Bounds 

7.Manifest Context Bounds

8.scala中的 协变,逆变

9.Existential Type

扫描二维码关注公众号,回复: 6227414 查看本文章

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 }

猜你喜欢

转载自blog.csdn.net/weixin_39966065/article/details/89944018