它提到了在重写方法中使用super的用法。
但是,在实际编写的样例程序中,我可以使用super关键字来访问超类中任何方法。
问题在于:为什么大多数网上讨论super的人总是谈论调用被覆盖的方法?
我的意思是,为什么不建议使用"使用super调用超类中的其他方法"呢?
另外一个问题: 我们不能在静态方法中使用super。编译器不允许我们这样做。
这是因为变量"super"属于对象而不是类,就像关键字"this"一样。静态方法属于类,静态方法没有变量"super"。
这表明旧方法仍然需要(并且与子类版本的方法有所不同),在这种情况下,您应该首先考虑不要覆盖它。父方法在子对象中仍然"有意义"。
在同一对象中使用两个名称相同但效果不同的方法听起来像是可读性的噩梦。鉴于两者都在使用,它们似乎应该是具有不同方法名称的单独方法,以清楚地显示它们的细微差别。
这在语义上是一个非常奇怪的事情。父类(非私有)方法是子类的方法,除非被覆盖,使用super.method()
和method()
有相同的效果,因此如果您后来确实重写了方法,则很可能会导致错误,这并不令人惊讶。
与此类似,您可以在接口方法前面加上public
,但它没有任何影响。
静态方法无法被覆盖,如果父类和子类恰好具有相同的方法名称,则编译器认为这只是一种巧合(尽管它会隐藏父类中的静态方法 - 而不是覆盖它)。鉴于静态方法无法使用super
关键字访问它变得没有意义。此外,您可以像下面这样访问Foo中的静态方法
Foo.staticMethod();
Foo.staticMethod();
。这与非静态方法不同,非静态方法中特定的继承链很重要,因此允许使用 super
会更不清晰。 - Richard Tinglesuper.SMA()
不可用是有道理的,因为这是在另一个类中调用静态方法的更迂回的方式。类层次结构对类的静态部分远不如重要;缺少super
引用静态方法进一步强调了这一点(实际上,我只能想到1种非常微小的方式,即子类完全关心其父类的静态部分)。 - Richard Tinglepublic class A {
public void foo() {...}
}
public class B extends A {
public void foo() { // The overriding method.
...
super.foo(); // invoking the overridden method.
...
}
}
子类中的方法调用了自己被覆盖的版本。你会在很多示例中看到它,因为它是最常见的使用情况。就这样。
另一方面,如果方法A.foo()
根本没有被覆盖,那么在B
中使用super.foo()
来调用它是合法的...但我认为这不是好的风格。首先,如果您随后在B
中添加一个覆盖方法,它可能会破坏代码。
super.f()
绕过了this.f()
。如果没有实现this.f()
,则不需要super
。否则,在this.f()
内部未调用时会有一些代码味道。
简而言之:无法找到许多合理的用途来调用super.f()
:super.f()
对任何已知问题都没有解决方案。
我只能想到以下情况:通过使用递归水平列出的框来布局矩形,每个框内部列出垂直列表的框,内部列出水平列表的框等。
public class SpecialBoxLayout extends BoxLayout {
@Override
public void layoutHor(...) {
... // Something extra, special
for
super.layoutVert(...);
...
}
@Override
public void layoutVert(...) {
...
for
super.layoutHor(...);
...
}
super.super.f()
一样。
它(调用super.f)是不好的风格,因为:
layout(Orientation.VERT, ...)
。import java.util.*;
class A {
public void methodOne() {
System.out.println("A.1");
methodTwo();
//super.methodTwo();
/*This above would lead to compilation error even though
it would work as intended - always print A.2.
Use instead for instance: ((A)this).methodTwo();*/
}
public void methodTwo() {
System.out.println("A.2");
}
}
class B extends A{
@Override
public void methodTwo() {
System.out.println("B.2");
}
public B() {
methodOne();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.methodTwo();
b.methodTwo();
}
}
你可以使用 super.method()
调用任何方法,但是你只能使用 super()
调用被覆盖的方法。
super()
调用父类的无参构造函数,但在方法中这是无效的,因为构造函数不是方法。 - Brandon