|NO.Z.00074|——————————|BigDataEnd|——|Hadoop&Scala.V01|——|Scala.v01|扩展|类型参数|
一、类型参数
### --- 扩展大纲
~~~ 类型参数
~~~ 泛型类、泛型函数、协变和逆变
~~~ Akka
### --- 类型参数
~~~ Scala的类型参数与Java的泛型是一样的,
~~~ 可以在集合、类、函数中定义类型参数,从而保证程序更好的健壮性。
### --- 泛型类
~~~ 泛型类,顾名思义,其实就是在类的声明中定义一些泛型类型,
~~~ 然后在类内部的字段或者方法,就可以使用这些泛型类型。
~~~ 使用泛型类,通常是需要对类中的某些成员,
~~~ 比如某些字段和方法中的参数或变量进行统一的类型限制,这样可以保证程序更好的健壮性和稳定性。
~~~ 如果不使用泛型进行统一的类型限制,那么在后期程序运行过程中难免会出现问题,
~~~ 比如传入了不希望的类型导致程序出问题。
~~~ 在使用泛型类的时候,比如创建泛型类的对象,只需将类型参数替换为实际的类型即可。
~~~ Scala自动推断泛型类型特性:直接给使用泛型类型的字段赋值时,Scala会自动进行类型推断。
### --- 泛型类的定义如下:
~~~ # 定义一个泛型类
class Stack[T1, T2, T3](name: T1) {
var age: T2 = _
var address: T3 = _
def getInfo: Unit = {
println(s"$name,$age,$address")
}
}
~~~ # 使用上述的泛型类,只需要使用具体的类型代替类型参数即可。
object GenericityDemo {
def main(args: Array[String]): Unit = {
//创建泛型类对象
val stack = new Stack[String, Int, String]("lisi")
stack.age = 20
stack.address = "北京"
stack.getInfo
}
}
二、泛型函数
### --- 泛型函数
~~~ 泛型函数,与泛型类类似,可以给某个函数在声明时指定泛型类型,然后在函数体内,
~~~ 多个变量或者返回值之间,就可以使用泛型类型进行声明,
~~~ 从而对某个特殊的变量,或者多个变量,进行强制性的类型限制。
~~~ 与泛型类一样,你可以通过给使用了泛型类型的变量传递值来让Scala自动推断泛型的实际类型,
~~~ 也可以在调用函数时,手动指定泛型类型。
### --- 案例:卡片售卖机,可以指定卡片的内容,内容可以是String类型或Int类型
object GenericityFunction {
def getCard[T](content: T) = {
content match {
case content: Int => s"card:$content is Int "
case content: String => s"card:$content is String"
case _ => s"card:$content"
}
}
def main(args: Array[String]): Unit = {
println(getCard[String]("hello"))
println(getCard(1001))
}
}
三、编程实现
### --- 编程代码
package yanqi.cn.part11
//定义一个泛型类
class Stack[T1, T2, T3](name: T1) {
var age: T2 = _
var address: T3 = _
def getInfo: Unit = {
println(s"$name,$age,$address")
}
}
object GenericityDemo {
def main(args: Array[String]): Unit = {
//创建泛型类的对象
val stack=new Stack[String,Int,String]("lisi")
stack.age=20
stack.address="北京"
stack.getInfo
}
}
### --- 编译打印
D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=61763:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\ScalaPro\out\production\ScalaPro;D:\JAVA\scala-2.12.2\lib\scala-library.jar;D:\JAVA\scala-2.12.2\lib\scala-reflect.jar yanqi.cn.part11.GenericityDemo
lisi,20,北京
Process finished with exit code 0
四、协变和逆变
### --- 协变和逆变
~~~ Scala的协变和逆变是非常有特色的,完全解决了Java中的泛型的一大缺憾!
~~~ 举例来说,Java中,如果有Professional是Master的子类,那么Card[Professionnal]是不是Card[Master]的子类?答案是:不是。因此对于开发程序造成了很多的麻烦。
~~~ 而Scala中,只要灵活使用协变和逆变,就可以解决Java泛型的问题。
~~~ 协变定义形式如:trait List[+T] {}
~~~ 当类型S是类型A的子类型时,则List[S]也可以认为是List[A}的子类型,即List[S]可以泛化为List[A],
~~~ 也就是被参数化,类型的泛化方向与参数类型的方向是一致的,所以称为协变(covariance)。
~~~ 逆变定义形式如:trait List[-T] {}
~~~ 当类型S是类型A的子类型,则Queue[A]反过来可以认为是Queue[S}的子类型,
~~~ 也就是被参数化类型的泛化方向与参数类型的方向是相反的,所以称为逆变(contravariance)。
~~~ # 小结:
~~~ 如果A是B的子类,那么在协变中,List[A]就是List[B]的子类; 在逆变中,List[A]就是List[B]的父类。
### --- 协变案例:只有大师以及大师级别以下的名片都可以进入会场
package yanqi.cn.part11
//大师
class Master
//专家
class Professor extends Master
//讲师
class Teacher
//这个是协变,Professor是Master的子类,此时Card[Profesor]也是Card[Master]的子类
class Card[+T]
object CovarianceDemo {
def enterMeet(card: Card[Master]): Unit = {
//只有Card[Master]及其子类Card[Professor]才能进入会场。
println("欢迎进入会场!")
}
def main(args: Array[String]): Unit = {
val masterCard = new Card[Master]
val professorCard = new Card[Professor]
val teacharCard = new Card[Teacher]
enterMeet(masterCard)
enterMeet(professorCard)
//此处就会报错
//enterMeet(teacharCard)
}
}
五、编程实现
### --- 编程代码
package yanqi.cn.part11
//大师
class Master
//专家
class Professor extends Master
//讲师
class Teacher
//定义协变
//class Card[+T]
//定义逆变
class Card[-T]
object ConvarianceDemo {
def enterMeet(card: Card[Professor]): Unit = {
//只有Card[Master]和它的子类才能进入会场
println("欢迎进入会场!")
}
def main(args: Array[String]): Unit = {
val masterCard = new Card[Master]
val professorCard = new Card[Professor]
val teacherCard = new Card[Teacher]
enterMeet(masterCard)
enterMeet(professorCard)
// enterMeet(teacherCard)
}
}
### --- 编译打印
D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=61585:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\ScalaPro\out\production\ScalaPro;D:\JAVA\scala-2.12.2\lib\scala-library.jar;D:\JAVA\scala-2.12.2\lib\scala-reflect.jar yanqi.cn.part11.ConvarianceDemo
欢迎进入会场!
欢迎进入会场!
Process finished with exit code 0
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv015-scala
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」