Java 如何从派生类外部调用超级方法(即:toString())

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6386343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:30:44  来源:igfitidea点击:

How to call a super method (ie: toString()) from outside a derived class

javacompiler-construction

提问by fedevo

existantial question

存在的问题

if i have a class hierarchy like:

如果我有一个类层次结构,如:

public class TestSuper {
    public static class A {
        @Override
        public String toString() { return "I am A"; }
    }
    public static class B extends A {
        @Override
        public String toString() { return "I am B"; }
    }
    public static void main(String[] args) {
        Object o = new B();
        System.out.println( o ); // --> I am B
        // ?????? // --> I am A 
    }
}    

From the main method, is it possible to call the toString of A when the instance is of type B ???

从 main 方法中,当实例是 B 类型时,是否可以调用 A 的 toString ???

of course, something like o.super.toString() doesn't compile ...

当然,像 o.super.toString() 这样的东西不能编译......

采纳答案by Jon Skeet

You can't, and very deliberately so: it would break encapsulation.

你不能,而且是故意这样做的:它会破坏封装。

Suppose you had a class which used a method to validate input by some business rules, and then call the superclass method. If the caller could just ignore the override, it would make the class pretty much pointless.

假设您有一个类,它使用一种方法来验证某些业务规则的输入,然后调用超类方法。如果调用者可以忽略覆盖,它将使该类变得毫无意义。

If you find yourself needing to do this, revisit your design.

如果您发现自己需要这样做,请重新审视您的设计。

回答by weekens

It's not possible, because toString() of A is overriden by B (I guess, you meant "class B extends A").

这是不可能的,因为 A 的 toString() 被 B 覆盖(我猜,你的意思是“B 类扩展 A”)。

回答by mrK

You can just add another method to call the super string. Something like:

您可以添加另一个方法来调用超级字符串。就像是:

public string getSuperString(){
    return super.toString();
}

回答by RamonBoza

In your code it is not possible, in case B extends A

在您的代码中这是不可能的,以防 B 扩展 A

public class TestSuper {
    public static class A {
        @Override
        public String toString() { return "I am A"; }
    }
    public static class B {
        @Override
        public String toString() { return "I am B"; }
    }
    public static void main(String[] args) {
        B b = new B();
        System.out.println( b ); // --> I am B
        A a = (A)b;
        System.out.println( a ); 
    }
} 

回答by Peter Lawrey

You can either

你可以

  • Add a method to A or B which you call instead.

     // to A
     public String AtoString() {
         return toString();
     }
     // OR to B
     public String AtoString() {
         return super.toString();
     }
    
  • Inline the code of A.toString() to where it is "called"

     // inlined A.toString()
     String ret = "I am A";
     System.out.println( ret );
    
  • 将方法添加到您调用的 A 或 B。

     // to A
     public String AtoString() {
         return toString();
     }
     // OR to B
     public String AtoString() {
         return super.toString();
     }
    
  • 将 A.toString() 的代码内联到它被“调用”的地方

     // inlined A.toString()
     String ret = "I am A";
     System.out.println( ret );
    

Both these options suggest a poor design in your classes, however sometimes you have existing classes you can only change in limited ways.

这两个选项都表明您的课程设计不佳,但是有时您有现有的课程,您只能以有限的方式进行更改。