Java中的super()

super()是否用于调用父构造函数? 请解释super().

.

.
534722 次浏览

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

是的。

请解释一下超级()。

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

这里是官方教程

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

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

“Java super”的快速谷歌会导致

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

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

它还可以用于从父类调用方法。例如super.aMethod()

更多信息和教程在这里

来源:Java:调用super()


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

说明:

enter image description here


单独的例子:

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用于调用父构造函数。假设你有这样一个代码块

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赋一个值。

一些事实:

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

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

检查程序1和程序2之间的区别。这里,程序2用Java证明了super()的第一个语句。

程序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();
}
}

输出:

< p > 200 < br > 200 < / p >

现在检查程序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();
}
}

输出:

< p > 100 < br > 200 < / p >

在程序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();
}
}

输出:

< p > 100 < br > 200 < / p >

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

< p > < >强构造函数 < /强>
在构造函数中,可以使用它而不带点来调用另一个构造函数。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是有用的,它允许你只在一个构造函数中编写一次所有的硬初始化代码,并从所有其他更容易编写的构造函数调用它。

< p > < >强的方法 < /强>
在任何方法中,都可以使用它和一个点来调用另一个方法。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只在使你的代码更具可读性的时候有用。

超级关键字可用于调用超类构造函数并引用超类的成员

当你用正确的参数调用super ()时,我们实际上调用了构造函数盒子< em > < / em >,它初始化变量< em > < / em >宽度< em > < / em >高< em > < / em >深度,通过使用相应参数的值引用它。你只剩下初始化它的增值权重。如果有必要,现在可以将类变量Box设置为私人。放在Box类私有修饰符的字段中,并确保您可以毫无问题地访问它们。

在超类中可以有多个重载版本的构造函数,因此可以使用不同的参数调用方法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;
}


}

只是超级();Alone将调用默认构造函数,如果类的超类中存在默认构造函数。但是必须自己显式地编写默认构造函数。如果你不这样做,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.
}


}

例如,在selenium自动化中,你有一个PageObject,它可以像这样使用它的父类构造函数:

public class DeveloperSteps extends ScenarioSteps {


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

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

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


class Implicit {
Implicit() {
}
}

超级是关键字。在子类方法定义中使用它来调用父类中定义的方法。父类的私有方法不能被调用。只有public和protected方法可以被super关键字调用。类构造函数也使用它来调用父类的构造函数。

查看在这里以获得进一步的解释。

我已经看到了所有的答案。但大家都忘了提一个非常重要的问题:

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

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

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

如果程序的类层次结构中有两个以上的班级,顶级类默认构造函数将得到被称为 第一个

下面是一个例子:

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

我愿意与代码分享我所了解的一切。

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

我们可以用SUPER做什么?

访问超类成员

如果你的方法覆盖了它的一些超类的方法,你可以通过使用关键字super来调用被覆盖的方法,比如super.methodName();

调用超类构造函数

如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会得到编译时错误。

看看下面的代码:


class Creature {
public Creature() {
system.out.println("Creature non argument constructor.");
}
}


class Animal extends Creature {
public Animal (String name) {
System.out.println("Animal one argument constructor");
}
public Animal (Stirng name,int age) {
this(name);
system.out.println("Animal two arguments constructor");
}
}


class Wolf extends Animal {
public Wolf() {
super("tigerwang",33);
system.out.println("Wolf non argument constructor");
}
public static void main(string[] args) {
new Wolf();
}
}
当创建一个对象时,JVM总是首先执行类中的构造函数 继承树的顶层。然后一直沿着遗传树。的 之所以会发生这种情况,是因为Java编译器会自动插入一个调用 赋给父类的无参数构造函数。如果没有非参数构造函数 在父类和子类中并没有显式地指出哪个构造函数是 在超类中执行,你将得到一个编译时错误 在上面的代码中,如果我们想成功地创建一个Wolf对象, 类必须执行。在这个过程中,Animal中的双参数构造函数 类被调用。同时,它显式地调用同一个参数中的单参数构造函数 类和单参数构造函数隐式调用生物中的非参数构造函数 类和非参数构造函数再次隐式调用Object中的空构造函数 类。< / p >
The super keyword in Java is a reference variable that is used to refer to the immediate parent class object.

Java超级关键字的使用

  • 超级可用于引用直接父类实例变量。

  • 超级可用于调用直接父类方法。

  • super ()可用于调用直接父类构造函数。

还有其他一些用途。

引用继承接口的默认方法:

import java.util.Collection;
import java.util.stream.Stream;


public interface SkipFirstCollection<E> extends Collection<E> {


@Override
default Stream<E> stream() {
return Collection.super.stream().skip(1);
}
}

还有一种很少使用的情况,在实例化静态子类时,使用限定super为超类构造函数提供外部实例:

public class OuterInstance {


public static class ClassA {


final String name;


public ClassA(String name) {
this.name = name;
}


public class ClassB {
public String getAName() {
return ClassA.this.name;
}
}
}


public static class ClassC extends ClassA.ClassB {
public ClassC(ClassA a) {
a.super();
}
}


public static void main(String[] args) {
final ClassA a = new ClassA("jeff");
final ClassC c = new ClassC(a);
System.out.println(c.getAName());
}
}

然后:

$ javac OuterInstance.java && java OuterInstance
jeff