Что на самом деле делает «расширяет»? - PullRequest
1 голос
/ 21 июня 2019

В настоящее время я изучаю понятия "абстракция классов" и "расширение" и мне интересно:
"Если я объявляю параметризованный конструктор внутри моего абстрактного класса, почему не будет работать расширение для другого класса, если я не объявлю себя конструктором с ключевым словом super, вызывающим параметры конструктора абстрактного класса?"

Я понимаю тот факт, что расширение помещает предыдущий абстрактный класс в расширенный и пытается вызвать конструктор по умолчанию, но мне было интересно, почему оно выдает ошибку.

Это потому, что конструктор был параметризован или просто потому, что пустой конструктор не существует?

Вызывает ли ключевое слово 1011 * что-то в этом роде?

Object myClass = new AbstractClass();

И пропущенные параметры являются причиной, по которой он выдает ошибку, поэтому что-то вроде этого будет правильным

Object myClass = new AbstractClass(int foo,float boo);

А если это так, то является ли ключевое слово super по существу, если позволите мне термином, "помещать" параметры, указанные в скобках, "внутри" конструктора?

Если это не так, что я не так делаю? Как это на самом деле работает?

Ответы [ 4 ]

2 голосов
/ 21 июня 2019

В этом контексте вы должны думать о ключевом слове extends как о том, что просто говорите, что класс является подклассом другого класса и больше ничего не делает.И что существуют правила, регулирующие работу подклассов и суперклассов.

Когда вы создаете подкласс, вы должны сначала создать его суперкласс.Например, чтобы создать Bird, сначала необходимо создать Animal.Это имеет смысл, не так ли?Чтобы продемонстрировать это в коде:

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

class Bird extends Animal {
    public Bird() {
        System.out.println("Bird");
    }
}

Выполнение new Bird() сначала напечатает Animal, а затем Bird, потому что сначала вызывается конструктор Animal, а затем конструктор Bird,На самом деле, конструктор Bird неявно вызывает конструктор суперкласса.Это можно записать так:

public Bird() {
    super();
    System.out.println("Bird");
}

Что теперь произойдет, если у суперкласса нет конструктора без параметров?Допустим, конструктор Animal теперь принимает String name в качестве аргумента.Вам все еще нужно сначала вызвать конструктор суперкласса, но super() не будет работать, потому что super() нужен строковый параметр!

Поэтому компилятор выдает ошибку.Это можно исправить, вызвав super() явный с параметром .

1 голос
/ 21 июня 2019

"Если я объявляю параметризованный конструктор внутри моего абстрактного класса, почему не будет продление на другую работу класса, если я не объявлю себя конструктор с супер ключевым словом, вызывающим параметры конструктор абстрактного класса? "

Потому что суперкласс говорит, что он ДОЛЖЕН быть конструктором, использующим этот объявленный конструктор, и другого пути нет. Это относится к каждому расширяющемуся классу - обязательный конструктор должен быть вызван.

То же самое происходит с любым классом, когда вы объявляете конструктор, отличный от конструктора по умолчанию. Например, имея

public class A{
   //no default no-arg ctor here
   public A(String name){
       ....
   }

}

public class B{
  //default no-arg ctor will be created
}

так тогда

  B b=new B();
    A a=new A(); //// INVALID!
    A a=new A("foobar"); // yeah that is it

То же самое относится и к расширению классов. Чтобы создать дочерний экземпляр, вы должны сначала «внутренне создать родительский экземпляр», вызывая super.constructor. Поскольку конструктора по умолчанию нет, следует использовать ЛЮБОЙ явно объявленный суперконструктор.

0 голосов
/ 21 июня 2019

Если я объявляю параметризованный конструктор внутри моего абстрактного класса, почему не будет работать расширение для другого класса, если я не объявлю себя конструктором с ключевым словом super, вызывающим параметры конструктора абстрактного класса?

В AbstractClass нет конструктора по умолчанию, поскольку вы определяете параметризованный конструктор. Если вы не определяете конструктор самостоятельно, неявно создается конструктор по умолчанию без аргументов. Теперь вы можете добавить его вручную или использовать только доступный конструктор (который параметризован) с super().


Пример вашего кода с определяющим конструктором без аргументов:

class AbstractClass {
    AbstractClass() {} // added manually since not created implicitly
    AbstractClass(int foo, float boo) {}
}
class RealClass extends AbstractClass {
    RealClass() { } // calls super() implicitly
}
AbstractClass myClass = new RealClass();

Пример вашего кода с вызовом super() с аргументами:

class RealClass extends AbstractClass {
    RealClass() {
        super(1, 2);
    }
}
class AbstractClass {
    AbstractClass(int foo, float boo) {}
}
AbstractClass myClass = new RealClass();
0 голосов
/ 21 июня 2019

При инициализации объекта конструктор всегда будет вызываться. Даже если вы не определите один конструктор, по умолчанию будет один без каких-либо параметров. Поэтому, если вы определяете конструктор в абстрактном классе, вы должны вызвать этот конструктор с помощью super().

Если вы не определите никаких конструкторов, то он будет неявно вызываться как конструктор по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...