为什么必须使用 super() 而不是其类名来调用超类构造函数?

huangapple go评论71阅读模式
英文:

Why superclass constructor must be called with super() and not with its class name?

问题

作为开始,规则很简单。子类能在父类之前存在吗?不能。 这就是为什么我们在创建子类时总是调用 super()。通过这种方式,超类的每个成员都会被“复制”到子类。

所以我会给出示例:

class Duck extends Animal {
    int size;

    public Duck(int size) {
        super();
        this.size = size;
    }
}

我的问题是为什么我们不能用 Animal() 而不是 super() 来调用 Animal 构造函数。或者,为什么我们不能这样做:

class Duck extends Animal {
    int size;

    public Duck(int size) {
        Animal();
        this.size = size;
    }
}

这两段代码不都应该能编译吗?我的意思是从技术上讲它们之间没有任何区别,编译器完全可以通过关键字 extends 知道 Duck 是一个 Animal。那么问题是什么呢?

英文:

For starters, rules are simple. Can the child exist before the parent? No. That is why we always call super() when creating a subclass. In that way, every member of the superclass gets "copied" to the subclass.

So I will give example:

  class Duck extends Animal {
    int size;

        public Duck(int size) {
            super();
            this.size = size;
        }
    }

My question is why can't we call Animal constructor with Animal() and not super(). Or, why can't we do this:

class Duck extends Animal {
    int size;

        public Duck(int size) {
            Animal();
            this.size = size;
        }
    }

Shouldn't both codes compile? I mean there is technically no difference between them and the compiler can pretty much know that Duck IS-A Animal by the keyword extends. So what is the problem then?

答案1

得分: 2

为什么必须使用 super() 而不是它的类名来调用超类构造函数?

简单来说,这是因为 Java 语法是这样设计的。

假设上,他们可以设计 Java 语法,使您可以使用超类的名称而不是 super。但事实并非如此。故事就到此为止了。(这些设计决策是在 1995 年之前就已经确定的,现在要改变已经太晚了。)

供记录,相关的语法在JLS 8.8.7.1中有详细规定,语法产生式为 ExplicitConstructorInvocation


1 - 我们不清楚为什么他们选择了 super 而不是其他可能性的细节。那是很久以前的事了,会议是秘密的。但是,作为一般规则,在编程语言中提供两种方式来表达相同的内容并没有实际意义。事实上,这可能只会使语言变得更难阅读...并且更难学习。

英文:

> Why superclass constructor must be called with super() and not with its class name?

Simple. It is because that is how the Java syntax was designed.

Hypothetically, they could have designed the Java syntax so that you could also<sup>1</sup> use the name of the superclass rather than super. But they didn't. End of story, really. (The design decisions were made prior to 1995, and it is way too late to change them.)

For the record, the relevant syntax is specified in JLS 8.8.7.1 and the grammar production is ExplicitConstructorInvocation.


<sup>1 - We don't know the details of why they chose super over other possibilities. It was a long time ago, and the meetings were private. However, as a general rule providing two ways to say the same thing in a programming language does not achieve anything practical. In fact, it probably only serves to make the language more difficult to read ... and learn.</sup>

答案2

得分: 1

一个好的编程语言是那种在尽量少的语法变化的情况下,让作者能够清楚地表达其意图的语言。变化越多,程序员就越需要记住更多的规则,编译器也需要更复杂的支持来处理所有这些变化。

假设我避开了Java的命名惯例,并在静态方法的名称中使用了大写字母:

class Duck extends Animal {
    int size;

    public Duck(int size) {
        Animal();       // super方法还是静态方法?
        this.size = size;
    }

    private static void Animal() {
        System.out.println("我是一个静态方法");
    }
}

Duck构造函数是在调用Animal构造函数还是静态方法?我们可以引入一个新的规则来涵盖这种情况,但这会增加更多的复杂性。

你提出的是实现完全相同目标的两种方式。当super本身就能很好地完成这个目标时,没有支持这种方式的必要。

为什么他们不允许我们使用parent()superconstructor()或者superclass()?责任在于要提供一个充分的理由来解释为什么应该支持这样做。

英文:

A good programming language is one that lets the author be expressive about their intent with as few syntactical variations as possible in which to achieve that. The more variations there are, the more rules a programmer has to carry around in their head, and the more complex a compiler has to be to support all those variations.

Suppose I eschew Java naming conventions and use a capital letter in the name of a static method:

class Duck extends Animal {
    int size;

    public Duck(int size) {
        Animal();       //super or static method?
        this.size = size;
    }

    private static void Animal() {
        System.out.println(&quot;I&#39;m a static method&quot;);
    }
}

Is the Duck constructor calling the Animal constructor or the static method? We could introduce a new rule which covers this case but it would be introducing more complexity.

What you are suggesting is two ways to achieve exactly the same thing. There is no reason to support that when super fulfills that purpose perfectly well on its own.

Why don't they also allow us to use parent() or superconstructor() or superclass()? The onus is on you to provide a compelling reason why it should be supported.

答案3

得分: 1

这就是为什么在创建子类时我们总是调用super()。

我认为答案就在问题中:
因为你正在创建一个子类。

我的问题是为什么我们不能用Animal()而不是super()来调用Animal构造函数。

从你的子类中,你无法访问“Animal()”构造函数。

如果你想要阅读更多关于你的困惑:https://www.w3schools.com/java/java_inheritance.asp

英文:

>That is why we always call super() when creating a subclass.

I think the answer is in the question:
Because you're creating a subclass.

>My question is why can't we call Animal constructor with Animal() and not super().

From within your subclass you have no access to the "Animal()" constructor.

If you want to read more about your dilemma: https://www.w3schools.com/java/java_inheritance.asp

huangapple
  • 本文由 发表于 2020年10月18日 19:56:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64413002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定