super.super java_为什么是super.super.method(); Java不允许?

问题

我读了this question并且认为如果可以写的话很容易解决(不是没有它可以解决):

@Override

public String toString() {

return super.super.toString();

}

我不确定它在许多情况下是否有用,但我不知道为什么不是,如果在其他语言中存在这样的东西。

你们有什么感想?

**编辑:**澄清:是的我知道,这在Java中是不可能的,我不会真的错过它。这不是我期望的工作,并且惊讶于编译错误。我刚才有了这个想法并想讨论它。

#1 热门回答(434 赞)

它违反了封装。你不应该绕过父类的行为。有时候能够绕过你的类的行为(特别是在同一个方法中)而不是你父母的行为是有意义的。例如,假设我们有一个基础"项目集合",一个表示"红色项目集合"的子类,以及表示"大红色项目集合"的子类。有:有意义:

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中的不变量被破坏了。

那有意义吗?

#2 热门回答(61 赞)

我认为Jon Skeet有正确的答案。我想通过castthis添加你可以从超类的超类中获取阴影变量:

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的例子)

但是,这不适用于方法调用,因为方法调用是根据对象的运行时类型确定的。

#3 热门回答(37 赞)

我认为以下代码允许在大多数情况下使用super.super ... super.method()。 (即使这样做很可取)

简而言之

创建祖先类型的临时实例

将原始对象的字段值复制到临时对象

在临时对象上调用目标方法

将修改后的值复制回原始对象

用法:

public class A {

public void doThat() { ... }

}

public class B extends A {

public void doThat() { /* don't call super.doThat() */ }

}

public class C extends B {

public void doThat() {

Magic.exec(A.class, this, "doThat");

}

}

public class Magic {

public static void exec(Class oneSuperType, ChieldType instance,

String methodOfParentToExec) {

try {

Type type = oneSuperType.newInstance();

shareVars(oneSuperType, instance, type);

oneSuperType.getMethod(methodOfParentToExec).invoke(type);

shareVars(oneSuperType, type, instance);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

private static void shareVars(Class clazz,

SourceType source, TargetType target) throws IllegalArgumentException, IllegalAccessException {

Class> loop = clazz;

do {

for (Field f : loop.getDeclaredFields()) {

if (!f.isAccessible()) {

f.setAccessible(true);

}

f.set(target, f.get(source));

}

loop = loop.getSuperclass();

} while (loop != Object.class);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值