Tôi nghĩ về nó theo cách này
+----------------+
| super |
+----------------+ <-----------------+
| +------------+ | |
| | this | | <-+ |
| +------------+ | | |
| | @method1() | | | |
| | @method2() | | | |
| +------------+ | | |
| method4() | | |
| method5() | | |
+----------------+ | |
We instantiate that class, not that one!
Hãy để tôi di chuyển lớp con đó sang trái một chút để tiết lộ những gì bên dưới ... (Trời ạ, tôi thích đồ họa 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).
Nói cách khác, trích dẫn từ Đặc tả ngôn ngữ Java :
Biểu mẫu super.Identifier
đề cập đến trường có tên Identifier
của đối tượng hiện tại, nhưng với đối tượng hiện tại được xem như một thể hiện của lớp cha của lớp hiện tại.
Biểu mẫu T.super.Identifier
đề cập đến trường có tên Identifier
của thể hiện bao quanh từ vựng tương ứng với T
, nhưng với đối tượng đó được xem như là một thể hiện của lớp cha của T
.
Theo thuật ngữ của layman, this
về cơ bản là một đối tượng (* đối tượng **; chính đối tượng mà bạn có thể di chuyển trong các biến), thể hiện của lớp được khởi tạo, một biến đơn giản trong miền dữ liệu; super
giống như một con trỏ tới một khối mã mượn mà bạn muốn được thực thi, giống như một lệnh gọi hàm đơn thuần và nó liên quan đến lớp nơi nó được gọi.
Do đó nếu bạn sử dụng super
từ lớp cha, bạn sẽ nhận được mã từ lớp superduper [ông bà] được thực thi), trong khi nếu bạn sử dụng this
(hoặc nếu nó được sử dụng ngầm) từ lớp cha, nó vẫn trỏ đến lớp con (vì không ai thay đổi nó - và không ai có thể).