【问题标题】:Is it unnecessary to put super() in constructor?没有必要将 super() 放在构造函数中吗?
【发布时间】:2010-01-13 02:42:58
【问题描述】:

如果我不将它放在子类的构造函数中,编译器不会自动放入它吗?

这意味着我什至不需要关心它?在一些文章中他们把它放出来了。

如果我有一个带参数的构造函数,这将是构造函数,还是需要一个没有参数列表的构造函数?

【问题讨论】:

    标签: java constructor super


    【解决方案1】:

    首先是一些术语:

    • 无参数构造函数:没有参数的构造函数;
    • 可访问的无参数构造函数:父类中对子类可见的无参数构造函数。这意味着它要么是公共的,要么是受保护的,或者如果两个类都在同一个包中,则包访问;和
    • 默认构造函数:当类中没有显式构造函数时,编译器添加的public no-args构造函数。

    所以所有类都至少有一个构造函数。

    子类构造函数可以指定在执行子类构造函数中的代码之前调用超类中的哪个构造函数作为他们做的第一件事。

    如果子类构造函数没有指定调用哪个超类构造函数,那么编译器会自动调用超类中可访问的无参数构造函数。

    如果超类没有无参数构造函数或者它不可访问,则不指定要调用的超类构造函数(在子类构造函数中)是编译器错误,因此必须指定。

    例如:

    public class Base { }
    public class Derived extends Base { }
    

    这很好,因为如果你没有显式添加构造函数,Java 会为你提供一个公共默认构造函数。

    public class Base { }
    public class Derived extends Base { public Derived(int i) { } }
    

    也不错。

    public class Base { public Base(String s) { } }
    public class Derived extends Base { }
    

    上面是编译错误,因为 Base 没有默认构造函数。

    public class Base { private Base() { } }
    public class Derived extends Base { }
    

    这也是一个错误,因为 Base 的无参数构造函数是私有的。

    【讨论】:

    • 所以,我猜标题中OP问题的答案是“是的,没有必要在子构造函数中包含super()”,因为super()是对“可访问”的调用无参数构造函数”。
    • "上面是编译错误,因为 Base 没有默认构造函数。"应该修改为“以上是编译错误,因为Base没有无参数构造函数。”
    • 取决于你的想法。我认为虽然没有必要 - 我不会说它没有必要。
    • @flow2k 这不是一个是或否的问题。在某些情况下,正如他的例子所证明的那样,这是不必要的,在某些情况下是必要的。 super() 将自动插入 this(...) 或 super(...) 未指定。如果超类不包含无参数构造函数或不可访问,则它不会编译。在这种情况下,有必要放置 super(...) 并指定构造函数。因此,可能没有可访问的无参数构造函数,在这种情况下 super 是必要的,并且必须具有可访问构造函数的参数。
    • @flow2k 请注意,如果超类只有一个构造函数并且它是私有的,那么由于没有可访问的构造函数,因此无法扩展该类(或实例化没有反射的类)。跨度>
    【解决方案2】:

    如果超类构造函数没有参数,Java 会自动为您调用它。如果它有参数,你会得到一个错误。

    src:http://java.sun.com/docs/books/tutorial/java/IandI/super.html

    【讨论】:

    • ...如果超类没有任何构造函数,它[默认构造函数]也将由编译器提供。提供的构造函数将具有与超类访问级别相同的访问级别。
    【解决方案3】:

    调用无参数超级构造函数只是浪费屏幕空间和程序员时间。无论您是否编写,编译器都会生成完全相同的代码。

    class Explicit() {
        Explicit() {
            super();
        }
    }
    
    class Implicit {
        Implicit() {
        }
    }
    

    更新(2018 年 12 月):

    编写显式 super() 有助于在 IDE 中导航源代码。

    截至 2018 年 12 月,Eclipse 和 IntelliJ 均未提供任何从派生类的构造函数轻松导航到基类的构造函数的方法。

    【讨论】:

    • 空的无参数隐式构造函数也是不必要的。
    • @Jon 在这种情况下,是的。但是如果你有一个带参数的构造函数,那么默认情况下不会创建无参数构造函数。
    【解决方案4】:

    即使你不调用默认父构造函数,也会从子默认构造函数中调用它。

    主要

    public class Main {
    
        public static void main(String[] args) {
            A a = new B();
        }
    }
    

    一个

    public class A {
    
        public A() {
            System.out.println("A");
        }
    }
    

    B

    public class B extends A {
    
        public B() {
            System.out.println("B");
        }
    }
    

    打印

    A
    B
    

    【讨论】:

      【解决方案5】:

      如果没有显式调用 super([arguments]),任何类构造函数总是调用“super()”,只有我们在编程时记住对超类构造函数的访问...... 当我们不扩展任何特定类时自动扩展 java.lang.Object 类

      【讨论】:

        【解决方案6】:
        abstract class Book
         {
        String title;
        String author;
        Book(String t,String a){
            title=t;
            author=a;
        }
        abstract void display();
        
        }    
        

        如果超类可以有一个无参数的构造函数。最好有一个无参数的构造函数,否则你必须传递带参数的超级构造函数。

        如果超类没有无参数构造函数或不可访问,则不指定要调用的超类构造函数(在子类构造函数中)是编译器错误,因此必须指定

        class MyBook extends Book{   
        int price ;
        public  MyBook(String t,String a,int price){
             super(t,a);
            this.price=price;
        }
        
        public void display(){
            System.out.println("Title: "+title);
         System.out.println("Author: "+author); 
        System.out.println("Price: "+price);
        
        }
        

        }

        【讨论】:

        • 第一段是不合逻辑的。
        猜你喜欢
        • 2013-02-18
        • 2018-05-06
        • 2014-02-17
        • 2015-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多