Scala 语言学习之泛型(7)
==>?泛型类 ????????---> T?可以代表任意类型 class?Person[T]{ ??private?var?name:T?=?_ ??def?setName(name:T)?=?{this.name?=?name} ??def?getName():T?=?{this.name} } //?***********测试***************** object?Person{ ??def?main(args:Array[String]):Unit?=?{ ????var?p?=?new?Person[String]() ????p.setName("hello") ????println(p.getName()) ??} }
==>?泛型函数 ????????--->?类型参数放在方法名之后 //*?泛型函数 //?创建一个固定类型的数组 //?普通函数 def?mkInt(elems:Int*)?=?Array[Int](elems:_*) def?mkString(str:String*)?=?"mkString" //?使用泛型函数,可以接收任意类型 def?mkArray[T:ClassTag](elems:T*)?=?Array[T](elems:_*) //?***********测试***************** //?普通函数只能传入相对应类型的参数 mkInt(1,2,3) mkString("hello",?"world") //?泛型函数可以传入任意类型的参数 mkArray(11.26,665,?84,?"hello") ==>?类型的上界和下界(Upper Bounds?和 Lower Bounds) ????????--->?用来定义泛型变量的范围 :?? ? ? ? ? --->?S <: T? (上界)????????S?必须是?T?类型的子类或类本身 class?Person1{ ??def?gender()?=?{println("gender")} } class?Man?extends?Person1{ ??override?def?gender()?=?{println("man")} } class?Women?extends?Person1{ ??override?def?gender()?=?{println("women")} object?UpperBoundsAndLowerBounds?{ ??//?定义一个泛型函数,通过上界的方式指定泛型的范围必须是?Person1?的子类或者Person1?类,并调用类中的?gender?方法 ??def?getGender[T?<:?Person1](g:T)?=?{g.gender()} ??def?main(args:Array[String]):?Unit?=?{ ????//?创建一个Person1?对象?,调用getGender?方法调用?Personal?中的?gender?方法 ????var?p:Person1?=?new?Person1 ????getGender(p) ????//?创建一个?Man?对象?,通过?getGender?方法调用Man?类中的?gender?方法 ????var?m?=?new?Man ????getGender(m) ??} } ? ? ? ? --->?U >: T(下界)????????U?必须是?T?类型的父类或类本身,此处不作示例,与上面例子类似,只是传入?getGender?方法中的参数必须是?Person1?类或其父类的对象 ==>?视图界定????<% ????????--->?与类型的上界相似,但是比类型的上界适用范围更广,除了所有的子类与类本身,它还允许通过隐式转换得到的类型 def?int2String[T?<%?String](x:T,?y:T)?=?{ ??println(x?+?"*****"?+?y) } //?***********测试***************** int2String("hello",?"world") implicit?def?int2String1(n:Int):String?=?{n.toString} int2String(100,?120) ==>?协变和逆变 ????????--->?协变:?泛型变量的值可以是类本身?????在类型参数前加一个 “+”?符号????子类转换为父类 //*?协变和逆变???在类型的前面加入?+号,就可以使类的特征变为协变了 //?将子类对象转换为父类对象称为协变?+ //?将父类对象转换为子类对象称为逆变?- package?demo1{ ??//?父类 ??class?Animal{} ??//?子类 ??class?Bird?extends?Animal ??class?Sparrow?extends?Bird ?? ??//?吃东西的类??????协变 ??class?EatSomethings[+T](t:T){} ??//?***********测试***************** ??object?Demo1{ ????def?main(args:Array[String]):?Unit={ ??????//?创建一个吃东西的对象 ??????var?c1:EatSomethings[Sparrow]?=?new?EatSomethings[Sparrow](new?Sparrow) ??????var?c2:EatSomethings[Animal]?=?c1 ????} ??} } ? ? ? ? --->?逆变:?泛型变量的值可以是父类或类本身????在类型参数前加一个 “?-?父类转换为子类????例:省略 ==>?隐式转换函数???? ????????--->?以关键字??implicit? ?申明 ? ? ? ? --->?单个参数 class?Fruit(name:String){ ??def?getFruitName():String?=?{name} } class?Monkey(f:Fruit){ ??def?say()?=?{println("Monkey?like?"?+?f.getFruitName())?} } //?***********测试***************** object?ImplicitDemo?{ ??def?main(args:Array[String]):Unit?=?{ ????var?f:Fruit?=?new?Fruit("bnanan") ????//?调用?fruit?的方法,希望?Monkey这个say?方法来实现 ????//?需要将?fruit?的对象转换为?monkey?对象,?即定义一个隐匿转换函数 ????implicit?def?fruit2Monkey(f:Fruit):Monkey?=?{new?Monkey(f)}?????//?将?fruit?对象转换为?Monkey?对象 ????//?调用Monkey中的?say?方法 ????f.say() ??} } ==>?隐式参数????使用?implicit?关键字申明的函数参数 ????????--->?可以使用隐式参数进行类型转换 //?隐式参数 def?testParam(implicit?name:String)?=?{println("The?value?is?"?+?name)} implicit?val?name:String?=?"这是一个隐式值" //?***********测试***************** testParam //--------------------------------------------------------------- //?带隐式参数的泛型函数 //?Ordered[T]?使类型可排序, //?????原型:def?smaller //?(implicit?order:T??????=>????Ordered[T]) def?smaller[T](a:T,?b:T)(implicit?order:T?=>?Ordered[T])?=?if(order(a)?<?b)?a?else?b //?***********测试***************** smaller(100,?56) smaller("hello",?"hi") ==>?隐式类????对类? 增加 implicit?限定 的类,其主要作用就是对类的功能增强 ????????--->?编写一个隐式类,使类实现更多的功能 object?testImplicit?{ ??//?定义一个隐式类 ??implicit?class?Calc(x:Int){ ????def?add(a:Int):Int?=?a?+?x ??} ??//?***********测试***************** ??def?main(args:Array[String]):Unit?=?{ ????println("两个数字的和:"?+?1.add(2)) ??} } ? ? ? ? --->?程序过程分析: ????????????????---?当 1.add(2)时,scala?的编译器不会报错,在当前域中查找,有没有 implicit?修饰的,同时可以将?Int?作为参数的构造器,并且具有 add?方法的类,通过查找,找到?Calc ????????????????---?利用隐式类?Calc?来执行?add?方法 ==>?个人总结: ????????---> 通过泛型,可以使我们定义一个模具,就像蛋糕的模具,我们可以分别放入草莓,蓝莓等不同的原料加工出不同口味的蛋糕来 ? ? ????--->?通过使用?上界,下界,视图界定,协变,逆变,对泛型的范围制定规则,使我们可以传入的符合规则的参数 ? ? ? ? --->?隐式函数,隐式参数,隐式类,会在程序运行时首先被查找,若有符合?以?implicit?修饰的参数,函数以及类,先执行,然后才运行程序 若总结有误,还请多多指教,谢谢!!! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |