Я попробовал ниже примера, он хорошо работает.
Я ожидал, что это выберет значение подкласса, так как объект не будет создан для суперкласса (поскольку это абстрактно). Но это берет значение поля суперкласса только.
Помогите мне понять то, что понятия позади этого?
abstract class SuperAbstract {
private int a = 2;
public void funA() {
System.out.println("In SuperAbstract: this.a " + a);
}
}
class SubClass extends SuperAbstract {
private int a = 34;
}
Я звоню new SubClass.funA();
Я ожидаю, что это распечатает 34, но это печатает 2.
P.S.: То, что я хочу знать, то, почему использование этого в абстрактном классе, не дающем мне ошибка?
Как ниже текста подчеркивает this
работал бы над экземпляром, и абстрактные классы не будут иметь экземпляра.
В методе экземпляра или конструкторе, это - ссылка на текущий объект — объект, метод которого или конструктора называют. Можно обратиться к любому члену текущего объекта из метода экземпляра или конструктора при помощи этого. от: http://java.sun.com/docs/books/tutorial/java/javaOO/thiskey.html
Чтобы ответить на вопрос в заголовке: Да , этот
может использоваться в абстрактном классе. Аннотация Животное
создается одновременно с созданием Собаки
.
Вы не можете переопределить поля так, как вы это пробовали. Поля «не виртуальные», как методы.
Из Краткого справочника Java: Перегрузка, переопределение, типы времени выполнения и объектная ориентация - методы переопределения
- поля не могут быть переопределены, но их можно скрыть , т.е. если вы объявляете поле в подклассе с тем же имя как одно в суперклассе, к полю суперкласса можно получить доступ только с использованием типа суперкласса или суперкласса
Если бы вы могли , это поле, вероятно, было бы как минимум защищено: -)
, поскольку объект не будет создан для суперкласса (поскольку он абстрактный)
Он фактически создан.
Ключевое слово abstract
только гарантирует, что при создании экземпляра оно создается в форме подкласса. Создавая экземпляр Dog
, вы одновременно создаете экземпляр Animal
! Ссылка this
в контексте Животного
, таким образом, всегда будет относиться к Собаке
или Кошке
или к чему угодно, но во всех случаях это относится к некоторому животному
. : -)
Как показано в примере ниже, ссылка 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 ()
. Вы бы увидели, что это правда.
Любое поле, объявленное в классе, является уникальным, даже если оно имеет то же имя, что и поле в базовом классе (т.е. только методы могут быть переопределены, но не поля). Следовательно, в производном классе есть два различных поля: SuperAbstract.a
и SubClass.a
. Тот факт, что базовым классом является абстрактный
, не влияет.
Ключевое слово abstract
просто означает, что класс не может быть создан, т.е. вы не можете написать new SuperAbstract ()
. Вы можете создать экземпляр только объекта подкласса, который должен переопределить все методы, отмеченные abstract
.