我读了这个问题,并认为如果有人可以这样写,这个问题就很容易解决(并不是说没有它就不能解决):
@Override
public String toString() {
return super.super.toString();
}
我不确定它在很多情况下是否有用,但我想知道为什么它没有,以及其他语言中是否存在类似的东西。
你们怎么看?
编辑:
澄清一下:是的,我知道,这在Java中是不可能的,我并不真的怀念它。这不是我期望的工作,并惊讶地得到一个编译器错误。我只是有了个想法,喜欢讨论一下。
它违反了封装。你不应该能够绕过父类的行为。有时能够绕过自己类的行为(特别是在同一个方法中),但不能绕过父类的行为是有意义的。例如,假设我们有一个基类“项目的集合”,一个子类表示“红色项目的集合”,该子类的一个子类表示“大红色项目的集合”。这是有道理的:
public class Items
{
public void add(Item item) { ... }
}
public class RedItems extends Items
{
@Override
public void add(Item item)
{
if (!item.isRed())
{
throw new NotRedItemException();
}
super.add(item);
}
}
public class BigRedItems extends RedItems
{
@Override
public void add(Item item)
{
if (!item.isBig())
{
throw new NotBigItemException();
}
super.add(item);
}
}
这很好- RedItems总是可以确信它包含的项目都是红色的。现在假设我们能够调用super.super.add():
public class NaughtyItems extends RedItems
{
@Override
public void add(Item item)
{
// I don't care if it's red or not. Take that, RedItems!
super.super.add(item);
}
}
现在我们可以添加任何我们喜欢的东西,而RedItems中的不变量被打破了。
明白吗?
它违反了封装。你不应该能够绕过父类的行为。有时能够绕过自己类的行为(特别是在同一个方法中),但不能绕过父类的行为是有意义的。例如,假设我们有一个基类“项目的集合”,一个子类表示“红色项目的集合”,该子类的一个子类表示“大红色项目的集合”。这是有道理的:
public class Items
{
public void add(Item item) { ... }
}
public class RedItems extends Items
{
@Override
public void add(Item item)
{
if (!item.isRed())
{
throw new NotRedItemException();
}
super.add(item);
}
}
public class BigRedItems extends RedItems
{
@Override
public void add(Item item)
{
if (!item.isBig())
{
throw new NotBigItemException();
}
super.add(item);
}
}
这很好- RedItems总是可以确信它包含的项目都是红色的。现在假设我们能够调用super.super.add():
public class NaughtyItems extends RedItems
{
@Override
public void add(Item item)
{
// I don't care if it's red or not. Take that, RedItems!
super.super.add(item);
}
}
现在我们可以添加任何我们喜欢的东西,而RedItems中的不变量被打破了。
明白吗?
我会把超级。如果可能的话,超级方法主体放在另一个方法中
class SuperSuperClass {
public String toString() {
return DescribeMe();
}
protected String DescribeMe() {
return "I am super super";
}
}
class SuperClass extends SuperSuperClass {
public String toString() {
return "I am super";
}
}
class ChildClass extends SuperClass {
public String toString() {
return DescribeMe();
}
}
或者如果你不能改变超超类,你可以试试这个:
class SuperSuperClass {
public String toString() {
return "I am super super";
}
}
class SuperClass extends SuperSuperClass {
public String toString() {
return DescribeMe(super.toString());
}
protected String DescribeMe(string fromSuper) {
return "I am super";
}
}
class ChildClass extends SuperClass {
protected String DescribeMe(string fromSuper) {
return fromSuper;
}
}
在这两种情况下,
new ChildClass().toString();
结果变成“我超级超级”
我认为乔恩·斯基特有正确答案。我只是想补充一点,你可以通过强制转换从超类的超类中访问阴影变量:
interface I { int x = 0; }
class T1 implements I { int x = 1; }
class T2 extends T1 { int x = 2; }
class T3 extends T2 {
int x = 3;
void test() {
System.out.println("x=\t\t" + x);
System.out.println("super.x=\t\t" + super.x);
System.out.println("((T2)this).x=\t" + ((T2)this).x);
System.out.println("((T1)this).x=\t" + ((T1)this).x);
System.out.println("((I)this).x=\t" + ((I)this).x);
}
}
class Test {
public static void main(String[] args) {
new T3().test();
}
}
它产生输出:
x= 3
super.x= 2
((T2)this).x= 2
((T1)this).x= 1
((I)this).x= 0
(例子来自JLS)
但是,这对方法调用不起作用,因为方法调用是基于对象的运行时类型确定的。