为了账号安全,请及时绑定邮箱和手机立即绑定

为什么Super.method();在Java中是不允许的?

为什么Super.method();在Java中是不允许的?

手掌心 2019-06-06 15:51:44
为什么Super.method();在Java中是不允许的?我读这个问题并认为,如果一个人能写到,那么这个问题就会很容易解决(不是说没有它就解决不了):@Overridepublic String toString() {     return super.super.toString();}我不确定它在很多情况下是否有用,但我想知道为什么如果这样的东西存在于其他语言中的话,它是不存在的。你们觉得怎么样?编辑:澄清一下:是的,我知道,这在Java中是不可能的,我并不是真的想念它。这不是我所期望的工作,我很惊讶地看到一个编译器错误。我刚想到这个主意,想讨论一下。
查看完整描述

3 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

这违反了封装。您不应该能够绕过父类的行为。有时绕开你的自己类的行为(特别是在同一方法中),而不是您的父类。例如,假设我们有一个基本的“项集合”,一个表示“红色项集合”的子类,以及一个表示“大型红色项集合”的子类。合理的做法是:

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.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都坏了。

这有道理吗?


查看完整回答
反对 回复 2019-06-06
?
偶然的你

TA贡献1841条经验 获得超3个赞

在大多数情况下,我认为下面的代码允许使用超级.方法()。(即使这么做很狡猾)

总之

  1. 创建祖先类型的临时实例
  2. 将字段的值复制到

    原版

    对象改为临时对象。
  3. 对临时对象调用目标方法
  4. 将修改后的值复制回原始对象

用法:

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 <Type, ChieldType extends Type> void exec(Class<Type> 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 <Type, SourceType extends Type, TargetType extends Type> void shareVars(Class<Type> 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);
    }}


查看完整回答
反对 回复 2019-06-06
  • 3 回答
  • 0 关注
  • 932 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信