[英]The behavior of the “this” keyword in abstract classes and generics
abstract class AnimalSerializer<E extends Animal> {
/**
* The type E (which extends Animal) is important here.
* I want to be able to write data that is specific to a subclass of an animal.
*/
abstract void writeAnimal(E animal);
abstract Animal readAnimal();
}
abstract class Animal {
AnimalSerializer<? extends Animal> serializer;
Animal(AnimalSerializer<? extends Animal> speciesSerializer) {
serializer = speciesSerializer;
}
void writeAnimalToFile() {
// This line fails to compile
serializer.writeAnimal(this);
}
}
class DogSerializer extends AnimalSerializer<Dog> {
@Override
void writeAnimal(Dog animal) {
// Write the stuff that is specific to the dog
// ...
}
@Override
Animal readAnimal() {
// Read the stuff specific to the dog, instantiate it, and cast it as an animal.
// ...
return null;
}
}
class Dog extends Animal {
String dogTag = "Data specific to dog.";
Dog() {
super(new DogSerializer());
}
}
我的問題與編譯失敗的行有關( serializer.writeAnimal(this)
)。 我不得不第一次提高語言規范以了解有關this
關鍵字的更多信息,但是我認為問題在於“ this”關鍵字的類型為Animal
,而有界通配符泛型<? extends Animal>
<? extends Animal>
僅支持屬於Animal子類的類型,而不支持Animal
類型本身。
我認為,考慮到無法實例化Animal,編譯器應該知道this
關鍵字的類型必須是擴展Animal的對象,並且this
關鍵字僅適用於已經存在的對象。
編譯器不知道為什么嗎? 我的猜測是,有一種情況可以解釋為什么不能保證this
關鍵字是Animal的子類。
此外,這種模式是否從根本上存在缺陷?
您的serializer
通用類型是? extends Animal
? extends Animal
。 您的this
類型是Animal
,也可以視為? extends Animal
? extends Animal
。 但是這兩個?
是不同的類型。 沒有限制讓編譯器知道它們是同一類型。
例如,我寫了一個Cat
類
class Cat extends Animal {
Cat(){
super(new DogSerializer()); // this is ok for your generic
}
}
這就是編譯器給您錯誤的原因。
除了Dean所說的之外:您可以使Animal
通用: Animal<S extends Animal>
然后序列化器變成AnimalSerializer<S> serializer
。 現在,它引用了Animal的“已知”子類。 並且extends變成了Dog extends Animal<Dog>
。 不幸的是,沒有辦法阻止Cat extends Animal<Dog>
。
您仍然必須強制執行以下操作: serializer.writeAnimal((S)this);
但是現在可以這樣做,因為您知道要強制轉換為哪個類。
這是弊端?
在泛型中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.