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

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

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

你们怎么看?

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


当前回答

在我看来,这是在Java中实现super.super.sayYourName()行为的干净方法。

public class GrandMa {  
    public void sayYourName(){  
        System.out.println("Grandma Fedora");  
    }  
}  

public class Mama extends GrandMa {  
    public void sayYourName(boolean lie){  
        if(lie){   
            super.sayYourName();  
        }else {  
            System.out.println("Mama Stephanida");  
        }  
    }  
}  

public class Daughter extends Mama {  
    public void sayYourName(boolean lie){  
        if(lie){   
            super.sayYourName(lie);  
        }else {  
            System.out.println("Little girl Masha");  
        }  
    }  
}  

public class TestDaughter {
    public static void main(String[] args){
        Daughter d = new Daughter();

        System.out.print("Request to lie: d.sayYourName(true) returns ");
        d.sayYourName(true);
        System.out.print("Request not to lie: d.sayYourName(false) returns ");
        d.sayYourName(false);
    }
}

输出:

请求说谎:d.sayYourName(true)返回奶奶Fedora 请求不要说谎:d.sayYourName(false)返回小女孩玛莎

其他回答

在我看来,这是在Java中实现super.super.sayYourName()行为的干净方法。

public class GrandMa {  
    public void sayYourName(){  
        System.out.println("Grandma Fedora");  
    }  
}  

public class Mama extends GrandMa {  
    public void sayYourName(boolean lie){  
        if(lie){   
            super.sayYourName();  
        }else {  
            System.out.println("Mama Stephanida");  
        }  
    }  
}  

public class Daughter extends Mama {  
    public void sayYourName(boolean lie){  
        if(lie){   
            super.sayYourName(lie);  
        }else {  
            System.out.println("Little girl Masha");  
        }  
    }  
}  

public class TestDaughter {
    public static void main(String[] args){
        Daughter d = new Daughter();

        System.out.print("Request to lie: d.sayYourName(true) returns ");
        d.sayYourName(true);
        System.out.print("Request not to lie: d.sayYourName(false) returns ");
        d.sayYourName(false);
    }
}

输出:

请求说谎:d.sayYourName(true)返回奶奶Fedora 请求不要说谎:d.sayYourName(false)返回小女孩玛莎

public class A {

     @Override
     public String toString() {
          return "A";
     }

}


public class B extends A {

     @Override
     public String toString() {
          return "B";
     }

}

public class C extends B {

     @Override
     public String toString() {
          return "C";
     }

}


public class D extends C {

     @Override
     public String toString() {
          String result = "";
          try {
                result = this.getClass().getSuperclass().getSuperclass().getSuperclass().newInstance().toString();
          } catch (InstantiationException ex) {
                Logger.getLogger(D.class.getName()).log(Level.SEVERE, null, ex);
          } catch (IllegalAccessException ex) {
                Logger.getLogger(D.class.getName()).log(Level.SEVERE, null, ex);
          }
          return result;
     }

}

public class Main {

     public static void main(String... args) {
          D d = new D();
          System.out.println(d);

     }
}

运行: 一个 BUILD SUCCESSFUL(总时间:0秒)

@Jon Skeet解释得好。 在我看来,如果有人想打电话给管理员。超方法则必须是想要忽略直接父元素的行为,但想要访问大父元素的行为。 这可以通过实例Of来实现。如下代码

public class A {
    protected void printClass() {
        System.out.println("In A Class");
    }
}

public class B extends A {

    @Override
    protected void printClass() {
        if (!(this instanceof C)) {
            System.out.println("In B Class");
        }
        super.printClass();
    }
}

public class C extends B {
    @Override
    protected void printClass() {
        System.out.println("In C Class");
        super.printClass();
    }
}

这是驾驶员课,

public class Driver {
    public static void main(String[] args) {
        C c = new C();
        c.printClass();
    }
}

它的输出将是

In C Class
In A Class

在这种情况下,类B printClass行为将被忽略。 我不确定这是一个理想的或好的做法,以达到超级。非常好,但它仍然有效。

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

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

明白吗?

在c#中,你可以像这样调用任何祖先的方法:

public class A
    internal virtual void foo()
...
public class B : A
    public new void foo()
...
public class C : B
    public new void foo() {
       (this as A).foo();
    }

你也可以在Delphi中这样做:

type
   A=class
      procedure foo;
      ...
   B=class(A)
     procedure foo; override;
     ...
   C=class(B)
     procedure foo; override;
     ...
A(objC).foo();

但是在Java中,你只能通过一些设备来实现这样的聚焦。一种可能的方法是:

class A {               
   int y=10;            

   void foo(Class X) throws Exception {  
      if(X!=A.class)
         throw new Exception("Incorrect parameter of "+this.getClass().getName()+".foo("+X.getName()+")");
      y++;
      System.out.printf("A.foo(%s): y=%d\n",X.getName(),y);
   }
   void foo() throws Exception { 
      System.out.printf("A.foo()\n");
      this.foo(this.getClass()); 
   }
}

class B extends A {     
   int y=20;            

   @Override
   void foo(Class X) throws Exception { 
      if(X==B.class) { 
         y++; 
         System.out.printf("B.foo(%s): y=%d\n",X.getName(),y);
      } else { 
         System.out.printf("B.foo(%s) calls B.super.foo(%s)\n",X.getName(),X.getName());
         super.foo(X);
      } 
   }
}

class C extends B {     
   int y=30;            

   @Override
   void foo(Class X) throws Exception { 
      if(X==C.class) { 
         y++; 
         System.out.printf("C.foo(%s): y=%d\n",X.getName(),y);
      } else { 
         System.out.printf("C.foo(%s) calls C.super.foo(%s)\n",X.getName(),X.getName());
         super.foo(X);
      } 
   }

   void DoIt() {
      try {
         System.out.printf("DoIt: foo():\n");
         foo();         
         Show();

         System.out.printf("DoIt: foo(B):\n");
         foo(B.class);  
         Show();

         System.out.printf("DoIt: foo(A):\n");
         foo(A.class);  
         Show();
      } catch(Exception e) {
         //...
      }
   }

   void Show() {
      System.out.printf("Show: A.y=%d, B.y=%d, C.y=%d\n\n", ((A)this).y, ((B)this).y, ((C)this).y);
   }
} 

objC.DoIt()结果输出:

DoIt: foo():
A.foo()
C.foo(C): y=31
Show: A.y=10, B.y=20, C.y=31

DoIt: foo(B):
C.foo(B) calls C.super.foo(B)
B.foo(B): y=21
Show: A.y=10, B.y=21, C.y=31

DoIt: foo(A):
C.foo(A) calls C.super.foo(A)
B.foo(A) calls B.super.foo(A)
A.foo(A): y=11
Show: A.y=11, B.y=21, C.y=31