我知道这个问题在here之前就已经问过了。但那里的答案并没有让我感到怀疑。
有人告诉我,它们可以防止类类型的混淆,下面的代码显示它们根本没有混淆。
所以,这不重要,对吧?
课程:
package Practice
abstract class Animal {
def name: String
}
abstract class Pet extends Animal {}
class Cat extends Pet {
override def name: String = "Cat"
}
class Dog extends Pet {
override def name: String = "Dog"
}以下是真正的困惑:
//Class with Upper Bound
class PetContainer[P <: Pet](p: P) {
def pet: P = p
}
//Class with Subtyping(Or Upcasting, I think they're the same)
class SimplePetContainer(p: Pet){
def pet: Pet = p
}司机代码:
val CatContainer: PetContainer[Cat] = new PetContainer[Cat](new Cat)
val DogContainer: SimplePetContainer = new SimplePetContainer(new Dog
println(CatContainer.pet.getClass)
println(DogContainer.pet.getClass)输出:
class Practice.Cat
class Practice.Dog
//Practice was the package就像我之前提到的,这些类被保存下来了。
所以我的问题是,上界在子类型上有什么优势?
发布于 2020-06-01 10:14:08
使用您的CatContainer,您知道CatContainer.pet是编译时的Cat。意味着编译器也知道这一点。所以你可以说
CatContainer.pet.meow()对于SimplePetContainer,您不再有关于pet内部的静态类型信息。
,正如我前面提到的,类是保留的。
在运行时,pet当然仍然知道它的类型(嗯,几乎,它知道它的类,在您的例子中,这就足够了,任何额外的类型信息,比如该类的泛型已经被删除了)。但是变量DogContainer.pet缺乏关于它包含什么样的Pet的信息。
i被告知,它们可以防止类类型的混淆。
编译器不会阻止您编写
val DogContainer = new SimplePetContainer(new Cat())但它会拒绝这个
val DogContainer = new PetContainer[Dog](new Cat())https://stackoverflow.com/questions/62129675
复制相似问题