Использование супер ключевого слова в Java - PullRequest
0 голосов
/ 14 марта 2020

У меня есть сомнения относительно печати оператора конструктора суперкласса , даже если я не использовал ключевое слово super () в подклассе.

class A
{
    int i;
    A()
    {
        System.out.println("A's constructor");
    }
}
class B extends A
{
    int i;
    B(int a , int b)
    {
        super.i=a;
        i=b;
    }
    void show()
    {
        System.out.println(super.i);
        System.out.println(i);
    }
}
class UseSuper
{
    public static void main(String[] args)
    {
        B b=new B(1,2);
        b.show();
    }
}

Вывод моей программы:

Конструктор A

1

2

Я не могу понять, почему я получаю конструктор A, напечатанный на моей консоли?

Ответы [ 3 ]

0 голосов
/ 14 марта 2020

Если конструктор не вызывает явно конструктор суперкласса, компилятор Java автоматически вставляет вызов в конструктор суперкласса без аргументов. Если суперкласс не имеет конструктора без аргументов, вы получите ошибку во время компиляции. У Object действительно есть такой конструктор, поэтому, если Object является единственным суперклассом, проблем нет.

Другими словами, конструктор B (int a, int b) неявно вызывает конструктор A (). В IDE просто измените A () на A (int i), и вы увидите сообщение об ошибке для конструктора B (int a, int b), например «Неявный супер-конструктор A () не определен. Должен явно вызывать другой конструктор».

0 голосов
/ 14 марта 2020

Проверьте следующие строки из https://docs.oracle.com/javase/tutorial/java/IandI/super.html


Примечание. Если конструктор не вызывает явно конструктор суперкласса, компилятор Java автоматически вставляет вызов конструктора без аргументов суперкласса. Если суперкласс не имеет конструктора без аргументов, вы получите ошибку во время компиляции. У Object действительно есть такой конструктор, поэтому, если Object является единственным суперклассом, проблем нет.


Если конструктор подкласса вызывает конструктор своего суперкласса, явно или неявно, вы можете подумать, что будет целая цепочка именованных конструкторов, вплоть до конструктора Object. На самом деле, это так. Это называется цепочкой конструктора, и вам нужно знать об этом, когда есть длинная линия происхождения класса.

Надеюсь, это рассеет ваши сомнения.

[Обновление]

Публикация этого обновления, чтобы очистить сомнения ОП, о которых он упоминал в своем комментарии ниже.

Следующий код не будет компилироваться, поскольку неявный супер-конструктор A() не был определены, и мы также не определили это явно. Обратите внимание, что неявный супер-конструктор A() определяется автоматически, если не было задано никакого другого конструктора с аргументами.

class A {
    int i;

    A(int x,int y){

    }
}

class B extends A {
    int i;

    B(int a, int b) {
        super.i = a;
        i = b;
    }

    void show() {
        System.out.println(super.i);
        System.out.println(i);
    }
}

public class UseSuper {
    public static void main(String[] args) {
        B b = new B(1, 2);
        b.show();
    }
}

[Другое обновление]

Публикация этого обновления, чтобы устранить еще одно сомнение ОП, о котором он упоминал в своем комментарии ниже.

Следующее код тоже не будет компилироваться, потому что супер-конструктор A() был объявлен как private, что не позволяет его вызывать конструктор дочернего класса.

class A {
    int i;

    private A() {
        System.out.println("A's constructor");
    }
}

class B extends A {
    int i;

    B(int a, int b) {
        super.i = a;
        i = b;
    }

    void show() {
        System.out.println(super.i);
        System.out.println(i);
    }
}

class UseSuper {
    public static void main(String[] args) {
        B b = new B(1, 2);
        b.show();
    }
}
0 голосов
/ 14 марта 2020

Когда класс расширяет другой класс, крайне важно сначала вызвать конструктор родительского класса и инициализировать его, прежде чем вызывать конструктор текущего класса.

Даже если визуально не вызывать super() в любой части вашего конструктора, Java сам вызывает конструктор класса A.

...