Scala进阶之路-Scala中的泛型介绍
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
通俗的讲,比如需要定义一个函数,函数的参数可以接受任意类型。我们不可能一一列举所有的参数类型重载函数。那么程序引入了一个称之为泛型的东西,这个类型可以代表任意的数据类型。说白了泛型就是对数据类型的约束,例如 List,在创建 List 时,可以传入整形、字符串、浮点数等等任意类型。那是因为 List 在类定义时引用了泛型。
一.Scala中的泛型
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.genericParadigm 7 8 import cn.org.yinzhengjie.genericParadigm.ClothesEnum.ClothesEnum 9 10 /** 11 * 泛型: 就是类型约束 12 * 定义一个泛型类Message 13 */ 14 abstract class Message[C](content: C) 15 /** 16 * 我们在继承发型类时,可以自定义传入的值,比如下面两个继承子类 17 */ 18 class StrMessage(content: String) extends Message(content) 19 20 class IntMessage[Int](content: Int) extends Message[Int](content) 21 /** 22 * 定义一个泛型类Clothes,主构造方法有3个。 23 */ 24 class Clothes[A, B, C](val clothType: A, val color: B, val size: C) 25 /** 26 * 定义一个枚举类ClothesEnum,它需要继承Enumeration 27 */ 28 object ClothesEnum extends Enumeration { 29 type ClothesEnum = Value 30 val 上衣, 内衣, 裤子 = Value 31 } 32 33 object ScalaGenericParadigm { 34 def main(args: Array[String]): Unit = { 35 val clth1 = new Clothes[ClothesEnum, String, Int](ClothesEnum.上衣, "black", 175) 36 println(clth1.clothType) 37 38 val clth2 = new Clothes[ClothesEnum, String, String](ClothesEnum.上衣, "black", "XL") 39 println(clth2.size) 40 41 val neiYi = new Clothes[ClothesEnum, String, String](ClothesEnum.内衣, "Pink", "X") 42 println(neiYi.color) 43 } 44 } 45 46 47 48 /* 49 以上代码执行结果如下: 50 上衣 51 XL 52 Pink 53 */
二.Scala的类型约束
1>.上界下界的图解说明
2>.类型约束的上界(Upper bounds)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie 7 8 /** 9 * <: #表示的是Scala泛型中的上界,相当于Java泛型中的"<T extends Comparable>" 10 * T<: Comparable[T] #表示T实现Comparable接口,不会发生隐式转换,除非用户显示的指定 11 */ 12 class ComparableGeneralObject[T<: Comparable[T]](a:T,b:T){ 13 /** 14 * @return : 返回比较大的数值 15 */ 16 def bigger = { 17 if (a.compareTo(b) > 0){ 18 a 19 }else{ 20 b 21 } 22 } 23 } 24 25 26 object ScalaUpperLowerBounds { 27 def main(args: Array[String]): Unit = { 28 29 val res1 = new ComparableGeneralObject(Integer.valueOf(10),Integer.valueOf(20)) 30 println(s"res1 ====> ${res1.bigger} ") 31 /** 32 * 注意,Predef.scala中有定义隐式方法,它可以把int转换成Integer,类似我们在java所说的自动拆箱和装箱。 33 * 而Predef在scala包下,因此其默认是导入的! 34 * 对了,还有一点就是上线界定不会隐式转换,因此我们在定义res2对象时,需要显示的指定其泛型,否则会编译不通过哟! 35 */ 36 val res2 = new ComparableGeneralObject[Integer](50,100) 37 println(s"res2 ====> ${res2.bigger} ") 38 39 } 40 } 41 42 43 44 /* 45 以上代码执行结果如下: 46 res1 ====> 20 47 res2 ====> 100 48 */
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie 7 8 9 /** 10 * <: #表示的是Scala泛型中的上界,相当于Java泛型中的"<T extends Comparable>" 11 * T<: Comparable[T] #表示T实现Comparable接口,不会发生隐式转换,除非用户显示的指定 12 */ 13 class ComparableGeneralObject[T<: Comparable[T]](a:T,b:T){ 14 /** 15 * @return : 返回比较大的数值 16 */ 17 def bigger = { 18 if (a.compareTo(b) > 0){ 19 a 20 }else{ 21 b 22 } 23 } 24 } 25 26 class TeacherOrdered(val name:String,val age:Int) extends Ordered[TeacherOrdered] { 27 /** 28 * 重写比较的方法,比较方法按照年龄来比较 29 */ 30 override def compare(that: TeacherOrdered): Int = { 31 this.age - that.age 32 } 33 /** 34 * 重写toString方法 35 */ 36 override def toString: String = { 37 this.name + "\t" + this.age 38 } 39 } 40 41 42 object TeacherDemo{ 43 def main(args: Array[String]): Unit = { 44 /** 45 * 丹尼斯·里奇,C语言之父,UNIX之父。曾担任朗讯科技公司贝尔实验室下属的计算机科学研究中心系统软件研究部的主任一 46 * 职。1978年与布莱恩·科尔尼干(Brian W. Kernighan)一起出版了名著《C程序设计语言(The C Programming Language)》, 47 * 现在此书已翻译成多种语言,成为C语言方面最权威的教材之一。2011年10月12日(北京时间为10月13日),丹尼斯·里奇去世, 48 * 享年70岁。 49 */ 50 val t1 = new TeacherOrdered("丹尼斯·里奇", 70) 51 /** 52 * 林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds, 1969年~ ),著名的电脑程序员、黑客。 53 * Linux内核的发明人及该计划的合作者。托瓦兹利用个人时间及器材创造出了这套当今全球最流行的操作系统 54 * (作业系统)内核之一。现受聘于开放源代码开发实验室(OSDL:Open Source Development Labs, Inc), 55 * 全力开发Linux内核。 56 */ 57 val t2 = new TeacherOrdered("Linus Benedict Torvalds", 49) 58 59 60 val res1 = new ComparableGeneralObject(t1,t2) 61 println(res1.bigger) 62 } 63 } 64 65 66 /* 67 以上代码执行结果如下: 68 丹尼斯·里奇 70 69 */