小记--------类型参数
参数类型其实就类似于java中的泛型,也是定义一种类型参数,比如在集合,在类,在函数中,定义类型参数,然后就可以保证使用到该类型参数的地方,肯定也只能是这种类型,从而实现程序更好的健壮性。
泛型类(案例:新生报到)
泛型类,其实就是在类的声明中,定义一些泛型类型,然后在类内部,比如field和method(参数和返回值)就可以使用这些泛型类型
使用泛型类,通常是需要对类中的某些成员,比如某些field和method中的参数或变量,进行统一的类型限制,这样可以保证程序更好的健壮性和稳定行
如果不适用泛型进行统一的类型限制,那么后期程序运行过程中,难免会出现问题,比如传入了不希望的类型,导致程序出问题
在使用类的时候,比如创建类的对象,将类型参数替换为实际的类型。即可,或者直接给使用了泛型类型的field赋值时,scala会自动进行类型推断。
泛型函数(案例:卡片售卖机)
泛型函数与泛型类类似,可以给某个函数咋声明时,指定泛型类型,然后在函数体内,多个变量或者返回值之间,就可以使用泛型类型进行声明,从而对某个特殊的变量,或者多个变量, 进行强制性的类型限制。
与泛型类一样,可以通过给使用了泛型类型的变量传递值来让scala自动推断泛型的实际类型, 也可以手动指定泛型类型。
上边界Bounds(案例:在派对上交朋友)
语法: class 类名[ T <: 父类名 ]
在指定泛型类型的时候,有时,我们需要对泛型类型的范围进行界定,而不是可以是任意的类型,比如:我们可能要求某个泛型类型,它就必须是某个类的子类,这样在程序中就可以放心地调用泛型类型继承的父类的方法,程序才能正常的使用和运行,此时就可以使用上下边界Bounds的特性。
scala的上下边界特性允许泛型类型必须是某个类的子类,或者必须是某个类的父类
上边界必须是 自己类 也就是父类, 或者是子类
下边界Bounds(案例:领身份证)
指定泛型类型必须是某个类的父类
View Bounds(案例:跟小狗交朋友)
上下边界Bounds,虽然可以让一种泛型类型,支持有父子关系的多种关系,但是,在某个类与上下边界Bounds指定的父子类型范围内的类都没有任何关系,则默认是肯定不能接受的。
View Bounds作为一种上下边界Bounds的加强版,支持可以对类型进行隐式转换,将指定的类型进行隐式转换后,再判断是否在边界指定的类型范围内
隐式转换
implicit def dog2person(obj:Object):Person = { if(obj.isInstanceOf[Dog]){ val dog = obj.asInstanceOf[Dog] new Person(dog.name) } else Nil }
Context Bounds(案例:使用scala内置的比较器比较大小)
Context Bounds 是一种特殊的Bounds,它会根据泛型类型的声明
比如:‘T : 类型’要求必须存在一个类型为‘类型[T]’的隐式值,其实个人认为,Context Bounds之所以叫Context,是因为它基于的是一种全局的上下文,需要使用到上下文中的隐式值以及注入
Manifest Context Bounds(案例: 打包饭菜)
在scala中,如果要实例化一个泛型数组,就必须使用Manifest Context Bounds , 也就是 如果数组元素类型为T的话, 需要为类或者函数定义[T:Manifest]泛型类型,这样才能实例化Array[T] 这种泛型数组
协变和逆变(案例:进入会场)
scala的协变和逆变可以解决java的泛型问题
举例:java中,如果有Professionnal是Master的子类,那么Cart[Professionnal] 不是Crad[Master]的子类
协变 (向下包容)
逆变(向上包容)
Existential Type
scala 有一种特殊的类型参数,就是Existential Type ,存在性类型
Array[ _ ] 就代表某种类型
作者:于二黑
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。