1、类型参数:
object ProTest4 {
def main(args: Array[String]): Unit = {
val n1 = new NumSum(4)
println(n1.sum(6))
}
}
class NumSum[T](val num : T){
def sum(num2 : T):String = {
val num3 = num + " _ " + num2
num3
}
}
输出:
4 _ 6
2 逆变,协变
协变:当我们定义一个协变类型List[+A]时,List[Child]可以是List[Parent]的子类型。
逆变:当我们定义一个逆变类型List[-A]时,List[Child]可以是List[Parent]的父类型。
object ProTest4 {
def main(args: Array[String]): Unit = {
val n1 = new NumSum(4)
println(n1.sum(6))
println("-*" * 20);
// 协变示例,定义一个子类,一个父类,可以将子类赋给父类
val covariant1 = new Covariant[Cat](new Cat)
println("- " * 20);
var covariant2 = new Covariant[Animal](new Animal)
covariant2 = covariant1
// 同时可以直接赋值: val covariant2:UnknownClass[Animal] = covariant1
println("- " * 20);
// 逆变示例,定义一个父类,一个子类,可以将父类赋给子类
val contravariant1 = new Contravariant[Animal](new Animal)
println("- " * 20);
var contravariant2 = new Contravariant[Cat](new Cat)
contravariant2 = contravariant1
}
}
class NumSum[T](val num : T){
def sum(num2 : T):String = {
val num3 = num + " _ " + num2
num3
}
}
class Animal{
println("It's a animal")
}
class Cat extends Animal{
println("Cat like fish !")
}
// 协变 (父类可以兼容子类)
class Covariant[+T](t : T){
println("Covariant")
}
// 逆变 (子类可以兼容父类)
class Contravariant[-T](t : T){
println("Contravariant")
}
输出:
4 _ 6
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
It's a animal
Cat like fish !
Covariant
- - - - - - - - - - - - - - - - - - - -
It's a animal
Covariant
- - - - - - - - - - - - - - - - - - - -
It's a animal
Contravariant
- - - - - - - - - - - - - - - - - - - -
It's a animal
Cat like fish !
Contravariant
3 下界lower bounds、上界upper bounds
协变类的类型参数可以用在方法的返回值的类型,在方法的参数类型上必须使用下界绑定 >:。
逆变类的类型参数可以用在方法的参数类型上,用做方法的返回值类型时必须使用上界绑定 <:。
object ProTest4 {
def main(args: Array[String]): Unit = {
val n1 = new NumSum(4)
println(n1.sum(6))
println("-*" * 40);
// 协变示例,定义一个子类,一个父类,可以将子类赋给父类
val covariant1 = new Covariant[Cat](new Cat)
println("- " * 20);
var covariant2 = new Covariant[Animal](new Animal)
covariant2 = covariant1
// 同时可以直接赋值: val covariant2:UnknownClass[Animal] = covariant1
println("- " * 20);
// 逆变示例,定义一个父类,一个子类,可以将父类赋给子类
val contravariant1 = new Contravariant[Animal](new Animal)
println("- " * 20);
var contravariant2 = new Contravariant[Cat](new Cat)
contravariant2 = contravariant1
println("- " * 40);
// 下边界
val lower1:LowerBounds[Animal] = new LowerBounds[Animal](new Cat)
lower1.lower(lower1)
lower1.lower(new Cat)
lower1.lower(new Animal)
println("- " * 20);
// 上边界
val upper1:UpperBounds[Cat] = new UpperBounds[Animal](new Animal)
// upper1.upper(upper1) 报错:
/*
* Multiple markers at this line:
* type mismatch; found : com.yanch.cn.UpperBounds[com.yanch.cn.Cat] required: U
* inferred type arguments [com.yanch.cn.UpperBounds[com.yanch.cn.Cat]] do not conform
* to method upper's type parameter bounds [U <: com.yanch.cn.Cat]
* inferred type arguments [com.yanch.cn.UpperBounds[com.yanch.cn.Cat]] do not conform
* to method upper's type parameter bounds [U <: com.yanch.cn.Cat]
*
*/
upper1.upper(new Cat)
// upper1.upper(new Animal) 报错:
/*
* Multiple markers at this line:
* type mismatch; found : com.yanch.cn.Animal required: U
* inferred type arguments [com.yanch.cn.Animal] do not conform to method upper's
* type parameter bounds [U <: com.yanch.cn.Cat]
*
*/
}
}
class NumSum[T](val num : T){
def sum(num2 : T):String = {
val num3 = num + " _ " + num2
num3
}
}
class Animal{
println("It's a animal")
}
class Cat extends Animal{
println("Cat like fish !")
}
// 协变 (父类可以兼容子类)
class Covariant[+T](t : T){
println("Covariant")
}
// 逆变 (子类可以兼容父类)
class Contravariant[-T](t : T){
println("Contravariant")
}
// 下边界
class LowerBounds[+T](t: T){
def lower[U >: T](u : U){
println(u)
}
}
// 上边界
class UpperBounds[-S](s: S){
def upper[U <: S](u : U){
println(u)
}
}
4 _ 6
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
It's a animal
Cat like fish !
Covariant
- - - - - - - - - - - - - - - - - - - -
It's a animal
Covariant
- - - - - - - - - - - - - - - - - - - -
It's a animal
Contravariant
- - - - - - - - - - - - - - - - - - - -
It's a animal
Cat like fish !
Contravariant
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
It's a animal
Cat like fish !
com.yanch.cn.LowerBounds@3feba861
It's a animal
Cat like fish !
com.yanch.cn.Cat@5b480cf9
It's a animal
com.yanch.cn.Animal@6f496d9f
- - - - - - - - - - - - - - - - - - - -
It's a animal
It's a animal
Cat like fish !
com.yanch.cn.Cat@723279cf
4 视图绑定View Bound <%
import scala.language.implicitConversions
object ProTest4 {
def main(args: Array[String]): Unit = {
/*
* 要求T必须有一种隐式转换能转换成Animal,也就是 T => Animal,否则以下:
* v1.mySay(new Test)
* v2.mySay2(new Test)
* 都将会报错,加入隐式转换,编译通过
*/
implicit def test2Animal(t: Test) = new Animal
val v1 = new ViewBounds[Animal]()
v1.mySay(new Animal)
v1.mySay(new Test)
println("-*" * 20)
val v2 = new ViewBounds2()
v2.mySay2(new Animal)
println("-*" * 20)
v2.mySay2(new Test)
}
}
class Animal{
def saySomething{
println("It's a animal")
}
}
class Test{}
// 类型参数在类参数上
class ViewBounds[T <% Animal](){
def mySay(t: T) = t.saySomething
}
// 类型参数在方法参数上
class ViewBounds2(){
def mySay2[T <% Animal](t: T) = t.saySomething
}
输出:
It's a animal
It's a animal
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
It's a animal
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
It's a animal