简体   繁体   English

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

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

For starters, rules are simple.对于初学者来说,规则很简单。 Can the child exist before the parent?孩子能先于父母存在吗? No. That is why we always call super() when creating a subclass.不。这就是我们在创建子类时总是调用super()原因。 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() .我的问题是为什么我们不能用Animal()而不是super()调用 Animal 构造函数。 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 .我的意思是在技术上它们之间没有区别,编译器几乎可以通过关键字extends知道Duck IS-A Animal So what is the problem then?那么问题是什么?

Why superclass constructor must be called with super() and not with its class name?为什么必须使用 super() 而不是类名调用超类构造函数?

Simple.简单的。 It is because that is how the Java syntax was designed.这是因为 Java 语法就是这样设计的。

Hypothetically, they could have designed the Java syntax so that you could also 1 use the name of the superclass rather than super .假设,他们可以设计 Java 语法,以便您也可以1使用超类的名称而不是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.) (设计决策是在 1995 年之前做出的,现在改变它们已经太晚了。)

For the record, the relevant syntax is specified in JLS 8.8.7.1 and the grammar production is ExplicitConstructorInvocation .作为记录,相关语法在JLS 8.8.7.1 中指定,语法产生ExplicitConstructorInvocationExplicitConstructorInvocation


1 - We don't know the details of why they chose super over other possibilities. 1 - 我们不知道他们为什么选择super不是其他可能性的细节。 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.事实上,它可能只会使语言更难阅读……和学习。

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:假设我避开 Java 命名约定并在静态方法的名称中使用大写字母:

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("I'm a static method");
    }
}

Is the Duck constructor calling the Animal constructor or the static method? Duck 构造函数是调用Animal 构造函数还是静态方法? 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.没有理由支持当super自己完美地实现了这个目的时。

Why don't they also allow us to use parent() or superconstructor() or superclass() ?为什么他们也不允许我们使用parent()superconstructor()superclass() The onus is on you to provide a compelling reason why it should be supported.该责任是提供一个令人信服的理由,应该得到支持。

That is why we always call super() when creating a subclass.这就是为什么我们在创建子类时总是调用 super() 的原因。

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().我的问题是为什么我们不能用 Animal() 而不是 super() 调用 Animal 构造函数。

From within your subclass you have no access to the "Animal()" constructor.在您的子类中,您无法访问“Animal()”构造函数。

If you want to read more about your dilemma: https://www.w3schools.com/java/java_inheritance.asp如果您想了解更多有关您的困境的信息: https : //www.w3schools.com/java/java_inheritance.asp

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

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