Я так думаю об этом
+----------------+
| super |
+----------------+ <-----------------+
| +------------+ | |
| | this | | <-+ |
| +------------+ | | |
| | @method1() | | | |
| | @method2() | | | |
| +------------+ | | |
| method4() | | |
| method5() | | |
+----------------+ | |
We instantiate that class, not that one!
Позвольте мне сдвинуть этот подкласс немного влево, чтобы показать, что находится под ним ... (Чувак, я действительно люблю графику ASCII)
We are here
|
/ +----------------+
| | super |
v +----------------+
+------------+ |
| this | |
+------------+ |
| @method1() | method1() |
| @method2() | method2() |
+------------+ method3() |
| method4() |
| method5() |
+----------------+
Then we call the method
over here...
| +----------------+
_____/ | super |
/ +----------------+
| +------------+ | bar() |
| | this | | foo() |
| +------------+ | method0() |
+-> | @method1() |--->| method1() | <------------------------------+
| @method2() | ^ | method2() | |
+------------+ | | method3() | |
| | method4() | |
| | method5() | |
| +----------------+ |
\______________________________________ |
\ |
| |
...which calls super, thus calling the super's method1() here, so that that
method (the overidden one) is executed instead[of the overriding one].
Keep in mind that, in the inheritance hierarchy, since the instantiated
class is the sub one, for methods called via super.something() everything
is the same except for one thing (two, actually): "this" means "the only
this we have" (a pointer to the class we have instantiated, the
subclass), even when java syntax allows us to omit "this" (most of the
time); "super", though, is polymorphism-aware and always refers to the
superclass of the class (instantiated or not) that we're actually
executing code from ("this" is about objects [and can't be used in a
static context], super is about classes).
Другими словами, цитата из спецификации языка Java :
Форма super.Identifier
относится к полю с именемIdentifier
текущего объекта, но при этом текущий объект рассматривается как экземпляр суперкласса текущего класса.
Форма T.super.Identifier
обращается к полю с именем Identifier
лексически включающего экземпляра, соответствующего T
, но с этим экземпляром, рассматриваемым как экземпляр суперкласса T
.
С точки зрения непрофессионала, this
это в основном объект (* объект **; тот же самый объект, который вы можете перемещать в переменных), экземпляр созданного класса, простая переменная в области данных; super
похож на указатель на заимствованный блок кода, который вы хотите выполнить, больше похож на простой вызов функции, и он относится к классу, в котором он вызывается.
Поэтому, если вы используете super
из суперкласса, вы получаете код из класса superduper [дедушка и бабушка], выполняемый), в то время как если вы используете this
(или если он используется неявно) из суперкласса, он продолжает указывать на подкласс (потому что никто его не изменил - и никто мог).