标签:Scala 逆变 Dog Pet 协变 new dogs def
协变:在期望接收一个基类集合的地方使用子类实例集合的能力
逆变:在期望接收一个子类集合的地方使用基类实例集合的能力
在默认情况下,scala不允许使用协变和逆变,称之为不变
举个例子:我们定义两个class,一个是Pet,一个是Dog,让Dog继承自Pet。
然后我们调用一个方法,在接Array[Pet]的地方传入Array[Dog]
在标红处,会提示type mismatch,说明默认情况不支持协变。
但是,我们可以通过特殊的语法来支持协变。
这里T <: Pet 表示T派生自Pet,Pet为T的上界,传入数组至少得是Array[Pet],或者其子类集合。
反之,也可以支持逆变,在接收子类集合的地方传入基类集合
这里Dog是T的下界。
前面介绍的,都是在方法参数做的型变。如果我们需要自定义数据格式的话,我们也可以使用”+T”或者“-T”来支持协变和逆变。
举个例子,前面我们定义的pets和dogs。
如果直接赋值的话,会提示type mismatch。
我们自己定义一个Array,“+T”表示支持协变。
petArray期望接收一个MyArray[Pet],但是接收了MyArray[Dog]。
反之,“-T”支持逆变
完整代码
object test extends App { def workWithPet(pets:Array[Pet]): Unit ={ } var dogs = Array[Dog](new Dog("bill"), new Dog("bob")) // workWithPet(dogs) def workWithPet2[T <: Pet](pets:Array[T]): Unit ={ } workWithPet2(dogs) var pets = Array[Pet](new Pet("bill"), new Pet("bob")) def workWithPet3[T >: Dog](dogs:Array[T]): Unit ={ } workWithPet3(pets) // pets = dogs // dogs = pets var dogArray = new MyArray[Dog]() var petArray = new MyArray[Pet]() petArray = dogArray var dogArray2 = new MyArray2[Dog]() var petArray2 = new MyArray2[Pet]() dogArray2 = petArray2 } class MyArray[+T]{ } class MyArray2[-T]{ } class Pet(name: String) { override def toString: String = name def behavior(): Unit = { println("This is a Pet.") } } class Dog(name: String) extends Pet(name: String) { override def toString: String = name override def behavior(): Unit = { println("This is a Dog.") } }
标签:Scala,逆变,Dog,Pet,协变,new,dogs,def 来源: https://www.cnblogs.com/gethinwang/p/15855418.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。