Java中的super()


Answers:


267

super() 调用不带参数的父构造函数。

它也可以与参数一起使用。即super(argument1),它将调用接受1类型的参数argument1(如果存在)的构造函数。

也可以用于从父级调用方法。即super.aMethod()

更多信息和教程在这里


9
注意:在第一种情况下,父类必须具有一个无参数的构造函数,否则将引发编译错误。
KNU 2014年

Nit:父/子术语对于类层次结构不是很好。(孩子不是父亲。)
aioobe 2015年

在哪里可以使用super有任何限制吗?
亚伦·弗兰克

2
@VivekChavda,确保孩子可以成为父母,就像学生可以成为老师一样,等等。但是我想你理解与动物->狗相比的区别。狗一定是动物。父母/孩子通常是一种关系(“父母有一个孩子”),而动物/狗是一种“是”关系。参见aioo.be/2016/06/29/a-child-is-not-always-a-parent.html
aioobe

2
@AaronFranke,“超级可以在哪里使用有任何限制?” -是的,super(...)只能用作构造函数中的第一条语句。
aioobe

154

一些事实:

  1. super() 用于调用直接父级。
  2. super() 可以与实例成员一起使用,即实例变量和实例方法。
  3. super() 可以在构造函数中使用以调用父类的构造函数。

好的,现在让我们实际实现这些要点super()

看看程序1和2之间的区别。在这里,程序2证明了我们super()在Java中的第一条陈述。

程序1

class Base
{
    int a = 100;
}

class Sup1 extends Base
{
    int a = 200;
    void Show()
    {
        System.out.println(a);
        System.out.println(a);
    }
    public static void main(String[] args)
    {
        new Sup1().Show();
    }
}

输出:

200
200

现在,检查程序2并尝试找出主要区别。

程序2

class Base
{
    int a = 100;
}

class Sup2 extends Base
{
    int a = 200;
    void Show()
    {
        System.out.println(super.a);
        System.out.println(a);
    }
    public static void main(String[] args)
    {
        new Sup2().Show();
    }
}

输出:

100
200

在程序1中,输出仅是派生类的。它无法打印基类或父类的变量。但是在程序2中,我们在输出super()变量a时使用了变量,而不是打印a派生类的变量值,而是打印a了基类的变量值。因此证明了它super()被用来调用直接父级。

好的,现在检查程序3和程序4之间的区别。

程序3

class Base
{
    int a = 100;
    void Show()
    {
        System.out.println(a);
    }
}

class Sup3 extends Base
{
    int a = 200;
    void Show()
    {
        System.out.println(a);
    }
    public static void Main(String[] args)
    {
        new Sup3().Show();
    }
}

输出:

200

这里的输出为200。当我们调用时Show()Show()派生类的函数被调用。但是,如果要调用Show()父类的函数,该怎么办?检出程序4以获得解决方案。

程序4

class Base
{
    int a = 100;
    void Show()
    {
        System.out.println(a);
    }
}

class Sup4 extends Base
{
    int a = 200;
    void Show()
    {
        super.Show();
        System.out.println(a);
    }
    public static void Main(String[] args)
    {
        new Sup4().Show();
    }
}

输出:

100
200

在这里,我们得到两个输出100和200。当Show()调用派生类的函数时,它首先调用Show()父类的Show()函数,因为在派生类的函数内部,我们Show()通过将super函数名称前的关键字。


4
您为什么不缩进源代码示例?是否有特定原因?
erikbwork

没有erikb,我想知道super()的用法。此后,我只去了
Mohan 2010年

在我的基类中,我用一个,两个,...参数重载了构造函数
Mohan 2010年

但是在派生类中,我使用了不带任何参数的super()。然后会发生什么事无论是自动调用基类的默认构造函数
磨憨

2
super()不是关键字。这是一个构造函数调用。super是关键字,而#1和#2仅在该定义下才有意义。
洛恩侯爵,

37

来源文章:Java:调用super()


是。super(...)将调用超类的构造函数。

插图:

在此处输入图片说明


独立示例:

class Animal {
    public Animal(String arg) {
        System.out.println("Constructing an animal: " + arg);
    }
}

class Dog extends Animal {
    public Dog() {
        super("From Dog constructor");
        System.out.println("Constructing a dog.");
    }
}

public class Test {
    public static void main(String[] a) {
        new Dog();
    }
}

印刷品:

Constructing an animal: From Dog constructor
Constructing a dog.

在我的基类中,我在构造函数中重载了一个,两个...。在派生类中,我使用了super()而没有任何参数。然后会发生什么事无论是自动调用基类的默认构造函数
磨憨

是。如果调用super(),它将调用不带参数的超类的构造函数。同样,如果执行super(arg1),它将调用1-参数构造函数,依此类推。
aioobe

如果基类中没有没有任何参数的构造函数,那么派生类调用super()会发生什么。
Mohan

1
没有。它不会编译。如果您自己提供构造函数,则不会生成自动/默认/无参数构造函数,因此super()将不是有效的调用。
aioobe 2010年

29

是super()用于调用父构造函数吗?

是。

请解释有关Super()的信息。

super()super关键字的特殊用法,您可以在其中调用无参数的父构造函数。通常,super关键字可用于调用覆盖的方法,访问隐藏的字段或调用超类的构造函数。

这是官方教程


5
super()用于调用父构造函数,super.myMethod()用于调用重写的方法。
肖恩·帕特里克·弗洛伊德

2
@seanizer或超类的任何其他方法(包括静态方法)(如果在范围内)。super只是对基类的引用。
atamanroman

3
我不认为super()用于调用基类方法。您可以使用super.method()。
Dheeraj Joshi

@ seanizer,@ Dheeraj:感谢您的反馈,我已经调整了答案。
Heinzi

7

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

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

class Implicit {
    Implicit() {
    }
}

我发现它在几节课中都使用过,不确定目的是什么。您的回答很有帮助。
令人沮丧的

6

是的,super()(小写)调用父类的构造函数。您可以包含参数:super(foo, bar)

还有一个super关键字,您可以在方法中使用该关键字来调用超类的方法

快速谷歌在“Java的超级”结果


4

那是正确的。Super用于调用父构造函数。所以假设您有一个像这样的代码块

class A{
    int n;
    public A(int x){
        n = x;
    }
}

class B extends A{
    int m;
    public B(int x, int y){
        super(x);
        m = y;
    }
}

然后,您可以为成员变量n分配一个值。


2

我已经看到了所有答案。但是每个人都忘记提及一个非常重要的观点:

super()应该在构造函数的第一行中调用或使用。


1

只是super(); 如果一个类的超类存在,则单独调用该默认构造函数。但是您必须自己明确编写默认构造函数。如果您不使用Java,则无需实现即可为您生成Java,请保存super();。,指的是通用的超类对象,因此您不能在子类中调用它。

public class Alien{
   public Alien(){ //Default constructor is written out by user
   /** Implementation not shown…**/
   }
}

public class WeirdAlien extends Alien{
   public WeirdAlien(){
   super(); //calls the default constructor in Alien.
   }

}

没有争执
洛恩侯爵,

1

例如,在硒自动化中,您有一个PageObject可以使用其父级的构造函数,如下所示:

public class DeveloperSteps extends ScenarioSteps {

public DeveloperSteps(Pages pages) {
    super(pages);
}........

1

我想与代码分享我所了解的。

java中的super关键字是一个引用变量,用于引用父类对象。它主要用于以下情况:-

1.将super与变量一起使用:

class Vehicle 
{ 
    int maxSpeed = 120; 
} 

/* sub class Car extending vehicle */
class Car extends Vehicle 
{ 
    int maxSpeed = 180; 

    void display() 
    { 
        /* print maxSpeed of base class (vehicle) */
        System.out.println("Maximum Speed: " + super.maxSpeed); 
    } 
} 

/* Driver program to test */
class Test 
{ 
    public static void main(String[] args) 
    { 
        Car small = new Car(); 
        small.display(); 
    } 
} 

输出:-

Maximum Speed: 120
  1. 使用super with方法:
/* Base class Person */
class Person 
{ 
    void message() 
    { 
        System.out.println("This is person class"); 
    } 
} 

/* Subclass Student */
class Student extends Person 
{ 
    void message() 
    { 
        System.out.println("This is student class"); 
    } 

    // Note that display() is only in Student class 
    void display() 
    { 
        // will invoke or call current class message() method 
        message(); 

        // will invoke or call parent class message() method 
        super.message(); 
    } 
} 

/* Driver program to test */
class Test 
{ 
    public static void main(String args[]) 
    { 
        Student s = new Student(); 

        // calling display() of Student 
        s.display(); 
    } 
}

输出:-

This is student class
This is person class

3.在构造函数中使用super:

class Person 
{ 
    Person() 
    { 
        System.out.println("Person class Constructor"); 
    } 
} 

/* subclass Student extending the Person class */
class Student extends Person 
{ 
    Student() 
    { 
        // invoke or call parent class constructor 
        super(); 

        System.out.println("Student class Constructor"); 
    } 
} 

/* Driver program to test*/
class Test 
{ 
    public static void main(String[] args) 
    { 
        Student s = new Student(); 
    } 
} 

输出:-

Person class Constructor
Student class Constructor

0

构造函数
在构造函数中,可以不带点使用它来调用另一个构造函数。super调用超类中的构造函数;this在此类中调用构造函数:

public MyClass(int a) {
  this(a, 5);  // Here, I call another one of this class's constructors.
}

public MyClass(int a, int b) {
  super(a, b);  // Then, I call one of the superclass's constructors.
}

super如果超类需要初始化自身,则很有用。this允许您仅在一个构造函数中编写一次所有硬初始化代码,并从所有其他更容易编写的构造函数中调用它,这很有用。

方法
在任何方法中,都可以将它与点一起使用以调用另一个方法。super.method()调用超类中的方法;this.method()调用此类中的方法:

public String toString() {
  int    hp   = this.hitpoints();  // Calls the hitpoints method in this class
                                   //   for this object.
  String name = super.name();      // Calls the name method in the superclass
                                   //   for this object.

  return "[" + name + ": " + hp + " HP]";
}

super在某些情况下很有用:如果您的类具有与您的超类相同的方法,则Java将假定您要在您的类中使用该方法;super允许您改为请求超类的方法。this仅用作使代码更具可读性的一种方式。


0

关键字可以用于调用超类构造函数和来指代超类的一个成员

当您使用正确的参数调用super()时,我们实际上调用了构造函数Box,该构造函数初始化变量widthheightdepth,并使用相应参数的值对其进行引用。您只需要初始化其增值权重即可。如有必要,您现在可以将变量Box作为私有类。放在Box类private修饰符的字段中,并确保您可以毫无问题地访问它们。

在超类中可以有几个重载版本的构造函数,因此您可以使用不同的参数调用方法super()。程序将执行与指定参数匹配的构造函数。

public class Box {

    int width;
    int height;
    int depth;

    Box(int w, int h, int d) {
        width = w;
        height = h;
        depth = d;
    }

    public static void main(String[] args){
        HeavyBox heavy = new HeavyBox(12, 32, 23, 13);
    }

}

class HeavyBox extends Box {

    int weight;

    HeavyBox(int w, int h, int d, int m) {

        //call the superclass constructor
        super(w, h, d);
        weight = m;
    }

}

0

super是一个关键字。在子类方法定义中使用它来调用超类中定义的方法。不能调用超类的私有方法。super关键字只能调用公共方法和受保护的方法。类构造函数还使用它来调用其父类的构造函数。

检查这里进一步的解释。


0

如前所述,在默认构造函数内部,在构造函数的第一行调用了一个隐式的 super()

这个super()自动从类层次结构的顶部开始调用构造函数链,然后向下移动层次结构。

如果程序的类层次结构中有两个以上的类,则顶级的默认构造函数将被调用 first

这是一个例子:

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

class B extends A{

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

class C extends B{ 

    public C() {
    System.out.println("Constructor C");
    }

    public static void main(String[] args) {
    C c1 = new C();
    }
} 

以上将输出:

Constructor A
Constructor B
Constructor C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.