简体   繁体   English

为什么 System.out.println(super) 不允许?

[英]Why is System.out.println(super) not permitted?

Why is System.out.println(super) not permitted?为什么System.out.println(super)不允许?

System.out.println(this);

This is OK and this.toString() is called and printed automatically.这没关系,并且this.toString()被自动调用和打印。 Of course, instance variable is OK instead of this .当然,实例变量可以代替this

However, this and super can be used in same way as I know.但是, thissuper可以以我所知道的相同方式使用。

System.out.println(super);

So why does this fail?那么为什么会失败呢? I think it's supposed to call super.toString() implicitly.我认为它应该隐式调用super.toString() I have read Java specification document, but I haven't found the reason.我已经阅读了 Java 规范文档,但我没有找到原因。

Check the grammar at http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html检查语法在http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html

The super keywords must always be followed by SuperSuffix, which cannot be empty. super关键字后面必须始终跟 SuperSuffix,不能为空。

So super can never stand alone as an expression.所以super永远不能单独作为一种表达方式。

Implementing a standalone variant of super that breaks virtual method dispatch would be an extremely bad idea.实现一个破坏虚拟方法分派的super的独立变体将是一个非常糟糕的主意。

Let's think about it for a while.让我们想一想。

abstract class Base {
    abstract String Description();
    String toString() { return "Base"; }
}
class Derived extends Base {
    String Description() { return "Derived description"; }
    String toString() { return "Derived"; }

    static void use(Base instance) {
        System.out.println(instance.toString());
        System.out.println(instance.Description());
    }
}

Now, let us take your suggestion and suppose that super is valid and does what you suggest;现在,让我们接受您的建议,并假设super是有效的并且按照您的建议执行; then we may write in Derived :那么我们可以在Derived中写:

class Derived extends Base {
    // Previous declarations omitted.
    void useSuper() { Derived.use(super); }
    void useThis() { Derived.use(this); }

    static void main() {
        Derived instance = new Derived();
        instance.useThis();
        instance.useSuper();
    }
}

Now, if I understood you, you suggest that the main function should print in order:现在,如果我理解你,你建议主要的 function 应该按顺序打印:

  • the implementation of toString() from Derived : "Derived".来自DerivedtoString()的实现:“Derived”。
  • the implementation of Description() from Derived : "Derived description" DerivedDescription()的实现:“派生描述”
  • the implementation of toString() from Base : "Base".来自BasetoString()的实现:“Base”。
  • the implementation of Description() from Base : It does not exist.来自BaseDescription()的实现:它不存在。 And the two solutions I can think of leads to bigger problems:我能想到的两种解决方案会导致更大的问题:
    • Raise an exception: congratulations, you can now break any program which relies on abstract methods actually being implemented without even thinking about it.提出一个例外:恭喜,您现在可以破坏任何依赖于实际实现的抽象方法的程序,甚至无需考虑它。 (How would you know that a function will call the abstract method?) (你怎么知道 function 会调用抽象方法?)
    • Return the implementation from Derived : breaks consistency.Derived返回实现:破坏一致性。

In short, such a use of the word super conceptually breaks object-oriented programming.简而言之, super这个词的这种使用在概念上破坏了面向对象的编程。

this refers to your current object . this是指您当前的object super refers to the super class , the class your current object directly inherits from (or it can be the super's constructor). super是指超级class , class 您当前的 object 直接继承自(或者它可以是超级的构造函数)。 So所以

System.out.println(this)

prints your object's toString() method, but打印对象的 toString() 方法,但是

System.out.println(super)

fails because super is NOT an object (and thus has no toString() method).失败,因为 super 不是 object (因此没有 toString() 方法)。

Super is relevant for calling of static methods only. Super 仅与调用 static 方法有关。 If you call non-static method using super that is actually reference to your object itself, ie to this .如果您使用实际上引用您的 object 本身的 super 调用非静态方法,即this For example you can say System.out.println(super.toString()) .例如,您可以说System.out.println(super.toString()) This will work and will run the toString() of actual class.这将起作用并将运行实际 class 的toString()

I think this is the reason that passing super as argument to other method is forbidden.我认为这就是禁止将super作为参数传递给其他方法的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM