Для ответа на вопрос в заголовке: Да , this
можно использовать в абстрактном классе. Аннотация Animal
создается одновременно с созданием Dog
.
Переопределяющие поля
Вы не можете переопределить поля так, как пытались. Поля "не являются виртуальными", как методы.
Из Java Краткий справочник: Перегрузка, переопределение, типы времени выполнения и ориентация объекта - методы переопределения
- поля не могут быть переопределены, но они могут быть скрыты т.е. если вы объявляете поле в подклассе с тем же именем, что и в суперклассе, доступ к полю суперкласса возможен только с использованием типа super или superclass
Если бы вы могли , поле, вероятно, должно быть хотя бы защищено: -)
Создание объектов абстрактных классов
поскольку объект не будет создан для суперкласса (как он абстрактен)
Это является фактически созданным.
Ключевое слово abstract
гарантирует, что при его создании оно создается в форме подкласса. Когда вы создаете экземпляр Dog
, вы одновременно создаете экземпляр Animal
! Таким образом, ссылка this
в контексте Animal
всегда будет ссылаться на Dog
или Cat
или что-то еще, но во всех случаях это относится к некоторому Animal
. : -)
Как показано в примере ниже, ссылка this
имеет смысл даже в абстрактном классе:
abstract class Animal {
public String name;
public Animal(String name) {
System.out.println("Constructing an Animal");
this.name = name;
}
public abstract void speak();
}
class Dog extends Animal {
public Dog(String name) {
super(name);
System.out.println(" Constructing a Dog");
}
public void speak() {
System.out.println("Bark! My name is " + name);
}
}
public class Test {
public static void main(String... args) {
new Dog("Woffy").speak();
}
}
Печать:
Constructing an Animal
Constructing a Dog
Bark! My name is Woffy
Обновление: Ссылка this
относится к тому же объекту в суперклассе, что и в подклассе.
Вы можете попробовать добавить
public Animal getSuperThis() { return this; }
до класса животных, и сделайте
System.out.println(this == getSuperThis());
в Dog.speak()
. Вы бы увидели, что он печатает правда.