jso*_*fry 86 java inheritance overriding super
public class SuperClass
{
public void method1()
{
System.out.println("superclass method1");
this.method2();
}
public void method2()
{
System.out.println("superclass method2");
}
}
public class SubClass extends SuperClass
{
@Override
public void method1()
{
System.out.println("subclass method1");
super.method1();
}
@Override
public void method2()
{
System.out.println("subclass method2");
}
}
public class Demo
{
public static void main(String[] args)
{
SubClass mSubClass = new SubClass();
mSubClass.method1();
}
}
Run Code Online (Sandbox Code Playgroud)
我的预期输出:
子类method1
超类method1
超类method2
实际产量:
子类method1
超类method1
子类方法2
我在技术上知道我已经覆盖了一个公共方法,但我认为因为我正在调用super,所以超级中的任何调用都会保留在super中,这种情况不会发生.关于如何实现这一点的任何想法?
Aar*_*lla 72
关键字super不会"粘".每个方法调用都是单独处理的,因此即使您SuperClass.method1()通过调用进行调用super,也不会影响将来可能进行的任何其他方法调用.
这意味着没有直接的方法来调用SuperClass.method2()从SuperClass.method1()没有去,虽然SubClass.method2(),除非你有一个实际的实例工作SuperClass.
您甚至无法使用Reflection实现所需的效果(请参阅文档java.lang.reflect.Method.invoke(Object, Object...)).
[编辑]似乎仍有一些混乱.让我尝试不同的解释.
当你调用时foo(),你实际上是在调用this.foo().Java只是让你省略this.在问题的例子中,类型this是SubClass.
因此,当Java执行代码时SuperClass.method1(),它最终会到达this.method2();
使用super不会更改指向的实例this.所以,电话将转入SubClass.method2()因为this是类型SubClass.
当您想象Java this作为隐藏的第一个参数传递时,可能更容易理解:
public class SuperClass
{
public void method1(SuperClass this)
{
System.out.println("superclass method1");
this.method2(this); // <--- this == mSubClass
}
public void method2(SuperClass this)
{
System.out.println("superclass method2");
}
}
public class SubClass extends SuperClass
{
@Override
public void method1(SubClass this)
{
System.out.println("subclass method1");
super.method1(this);
}
@Override
public void method2(SubClass this)
{
System.out.println("subclass method2");
}
}
public class Demo
{
public static void main(String[] args)
{
SubClass mSubClass = new SubClass();
mSubClass.method1(mSubClass);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您按照调用堆栈,您可以看到this永远不会更改,它始终是创建的实例main().
你正在使用this实际引用"你正在使用的对象的当前运行实例" 的关键字,也就是说,你正在调用this.method2();你的超类,也就是说,它会调用你对象上的method2()重新使用,这是SubClass.
我是这样想的
+----------------+
| super |
+----------------+ <-----------------+
| +------------+ | |
| | this | | <-+ |
| +------------+ | | |
| | @method1() | | | |
| | @method2() | | | |
| +------------+ | | |
| method4() | | |
| method5() | | |
+----------------+ | |
We instantiate that class, not that one!
Run Code Online (Sandbox Code Playgroud)
让我将该子类向左移动一点,以显示下面的内容...(老兄,我确实喜欢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).
Run Code Online (Sandbox Code Playgroud)
换句话说,引用Java语言规范:
该表单
super.Identifier引用Identifier当前对象的命名字段,但是将当前对象视为当前类的超类的实例。表单
T.super.Identifier是指与Identifier相对应的词汇包围实例的名称字段T,但将该实例视为的超类的实例T。
用外行的话来说,this基本上是一个对象(* the **对象;您可以在变量中移动的同一对象),实例化类的实例,数据域中的普通变量;super就像是指向要执行的借用代码块的指针,更像是单纯的函数调用,它相对于被调用的类。
因此,如果您super从超类使用,则从超级duper类[祖父母]获得代码,而如果您this从超类使用(或隐式使用)代码,则该代码将始终指向子类(因为没有人更改它,并且没人可以)。