Разница между ключевыми словами "this" и "super" в Java
В чем разница между ключевыми словами this
и super
?
Оба используются для доступа к конструкторам классов, верно? Можете объяснить, как они различаются и в каких ситуациях следует использовать каждое из них?
5 ответ(ов)
Давайте рассмотрим представленную ситуацию.
В вашем коде у вас есть класс Animal
с методом eat()
, который выводит строку "animal : eat". Затем у вас есть класс Dog
, который наследует от Animal
и переопределяет метод eat()
, выводя "dog : eat". В классе Dog
также есть метод anotherEat()
, который вызывает super.eat()
, то есть метод родительского класса Animal
.
Когда вы выполняете код в методе main
, происходит следующее:
- Создается объект
Animal
, и вызывается методa.eat()
, который выводит "animal : eat". - Далее создается объект
Dog
, и при вызовеd.eat()
выполняется переопределенный метод этого класса, который выводит "dog : eat". - Затем вызывается метод
d.anotherEat()
, который вызываетsuper.eat()
. Посколькуsuper.eat()
ссылается на метод родительского классаAnimal
, он выводит "animal : eat".
Если бы вместо super.eat()
вы использовали this.eat()
, то при этом вызвался бы переопределенный метод eat()
из класса Dog
, и вывод было бы "dog : eat".
Таким образом, вывод программы будет следующим:
animal : eat
dog : eat
animal : eat
Всякий раз, когда вы хотите вызвать метод родительского класса, используйте super
, а если хотите вызвать метод текущего (дочернего) класса, используйте this
.
super
используется для доступа к методам базового класса, тогда как this
предназначен для доступа к методам текущего класса.
Расширяя это понятие, если вы пишете super()
, это относится к конструктору базового класса, а если вы пишете this()
, это относится к конструктору того класса, в котором вы пишете этот код.
this
— это ссылка на объект, типизированный текущим классом, а super
— ссылка на объект, типизированный классом-родителем.
В конструкторе this()
вызывает конструктор, определенный в текущем классе, тогда как super()
вызывает конструктор, определенный в классе-родителе. Этот конструктор может быть определен в любом классе-родителе, но будет ссылаться на тот, который переопределен ближе к текущему классу. Вызовы других конструкторов таким образом могут выполняться только в первой строке конструктора.
Вызов методов работает аналогичным образом. Вызов this.method()
вызывает метод, определенный в текущем классе, в то время как super.method()
будет вызывать тот же метод, определенный в классе-родителе.
Из вашего вопроса я понимаю, что вы на самом деле спрашиваете о том, как использовать this
и super
в цепочке конструкторов; например:
public class A extends B {
public A(...) {
this(...);
...
}
}
в отличие от
public class A extends B {
public A(...) {
super(...);
...
}
}
Разница здесь проста:
- Форма с
this
вызывает конструктор в текущем классе, т.е. в классеA
. - Форма с
super
вызывает конструктор в непосредственном суперклассе, т.е. в классеB
.
this
ссылается на текущий экземпляр класса.
super
ссылается на родительский класс текущего класса (в котором используется ключевое слово super
).
Используя this
, вы можете получить доступ к методам и атрибутам текущего класса (включая его собственные закрытые методы и атрибуты).
super
позволяет получить доступ к публичным и защищённым методам и атрибутам родительского (базового) класса. Доступ к закрытым методам и атрибутам родительского класса невозможен.
Что значит 'synchronized'?
Инициализация ArrayList в одну строчку
Почему нет ConcurrentHashSet, если есть ConcurrentHashMap?
Как объявить массив в одну строку?
Какие проблемы следует учитывать при переопределении equals и hashCode в Java?