逆变 协变 不变

首页scala逆变 协变 不变(2018年11月28日)
class Animal {}
class Bird extends Animal {}
class Chicken extends Bird {}

//逆变
class Covariant1[-T](t:T){}
val cov01 = new Covariant1[Animal](new Animal)
val cov02:Covariant1[Chicken] = cov01

//协变
class Covariant2[+T](t:T){}
val cov11 = new Covariant2[Bird](new Bird)
val cov12:Covariant2[Animal] = cov11

//不变
class Covariant3[T](t:T){}
val cov21 = new Covariant3[Bird](new Bird)
val cov22:Covariant3[Bird] = cov21

例1:

class Earth {
  def sound(){
    println("hello !")
  }
}
class Animal extends Earth{
  override def sound() ={
    println("animal sound")
  }
}
class Bird extends Animal{
  override def sound()={
    println("bird sounds")
  }
}

// 协变
println("+T 协变测试")
// 定义一个协变容器类Container
class Space[+T]{
  println("hello space")
}
var a =new Space[Animal]
//上面一句 定义了变量a 是Space[Animal] 类型
//下面一句 赋值一个Animal子类的过去 也成功 代码 +T的意思是子类可以赋给父类变量
a = new Space[Bird]
// 因为Earth是Animal的父类 所以下面这句不通过
// a = new Space[Earth]

// 逆变
println("-T 逆变测试")
// 定义一个逆变容器类Container
class Space1[-T]{
  println("hello space")
}
// 完全是上面的反方向 想让子类指向父类的引用
// 正常思维 子类是父类的扩展 子类有的父类不一定有
// 所以把一个父类实例赋给子类实例 调用没有的函数时 会发生错误
// 暂时不明白这样设计的好处是什么 = =
var b =new Space1[Animal]
b = new Space1[Earth]
// 因为Bird是其子类 不是父类 所以编译不通过

// b = new Space1[Bird]

标签: none

评论已关闭