CC00074.scala——|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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yanqi_vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值