构造函数里有必要放super()吗?

问题描述 投票:0回答:7

如果我不将其放入子类的构造函数中,这不是由编译器自动放入的吗?

也就是说我根本不需要关心它?在一些文章中他们把它拿出来了。

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

java constructor super
7个回答
265
投票

首先一些术语:

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

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

子类构造函数可以指定在执行子类构造函数中的代码之前调用超类中的哪个构造函数。

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

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

例如:

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 的无参数构造函数是私有的。


63
投票

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

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


29
投票

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

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

class Implicit {
    Implicit() {
    }
}

更新(2018 年 12 月):

编写显式

super()
有助于在 IDE 中浏览源代码。

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


8
投票

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

主要

public class Main {

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

A

public class A {

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

B

public class B extends A {

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

打印

A
B

1
投票

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


0
投票

让我们记住超级关键字.. 它只是调用超类构造函数来创建对象。

情况1:有超类时

class Base {}
class Derived{}

这里 super 关键字是隐式添加在派生类中的。

class Base {}
class Derived extends Base {super();}

所以上面的代码与此相同

情况2:当有超类但构造函数重载时

class Base{
   Base(int x) {
        System.out.println("Base");
    }
}
class Derived extends Base {
    Derived() {
        super(); // here super will give ERROR as there is no default constructor present because we overloaded the constructor
        super(2); // will work, but without this it will not work as we have to call constructor of super class
    }
}

情况3:当没有您定义的超类时。

我们知道每个类都是Object类的子类..或者我们可以说基类是所有类的超类。 所以现在添加或不添加 super 没有任何意义..通过 jvm 它将默认添加。


-2
投票
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);

}

}

© www.soinside.com 2019 - 2024. All rights reserved.