我读了这个问题,并认为如果有人可以这样写,这个问题就很容易解决(并不是说没有它就不能解决):

@Override
public String toString() {
    return super.super.toString();
}

我不确定它在很多情况下是否有用,但我想知道为什么它没有,以及其他语言中是否存在类似的东西。

你们怎么看?

编辑: 澄清一下:是的,我知道,这在Java中是不可能的,我并不真的怀念它。这不是我期望的工作,并惊讶地得到一个编译器错误。我只是有了个想法,喜欢讨论一下。


当前回答

关键字super只是在超类中调用方法的一种方法。 在Java教程中:https://docs.oracle.com/javase/tutorial/java/IandI/super.html

如果您的方法覆盖了它的父类的方法之一,您可以通过使用关键字super调用被覆盖的方法。

不要相信这是一个超对象的引用!!不,它只是在超类中调用方法的关键字。

这里有一个例子:

class Animal {
    public void doSth() {
        System.out.println(this);   // It's a Cat! Not an animal!
        System.out.println("Animal do sth.");
    }
}

class Cat extends Animal {
    public void doSth() {
        System.out.println(this);
        System.out.println("Cat do sth.");
        super.doSth();
    }
}

当你调用cat.doSth()时,类Animal中的方法doSth()将打印这个,它是一只猫。

其他回答

除了其他人提出的非常好的观点之外,我认为还有另一个原因:如果超类没有超类怎么办?

因为每个类都自然地扩展(至少)Object,所以super.whatever()总是引用超类中的一个方法。但是如果你的类只扩展Object呢?超级指的是什么?该如何处理该行为-编译器错误,空指针,等等?

我认为不允许这样做的主要原因是它违反了封装,但这可能也是一个小原因。

使用反射,似乎至少可以获得超类的超类的类,尽管不一定是它的实例;如果这可能是有用的,请考虑Javadoc http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getSuperclass()

我认为以下代码允许在大多数情况下使用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 <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);
    }
}

我会把超级。如果可能的话,超级方法主体放在另一个方法中

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();

结果变成“我超级超级”

public class SubSubClass extends SubClass {

    @Override
    public void print() {
        super.superPrint();
    }

    public static void main(String[] args) {
        new SubSubClass().print();
    }
}

class SuperClass {

    public void print() {
        System.out.println("Printed in the GrandDad");
    }
}

class SubClass extends SuperClass {

    public void superPrint() {
        super.print();
    }
}

输出:打印在祖父