В настоящее время я изучаю концепцию «абстракции класса» и «расширения» и задаюсь вопросом:
«Если я объявлю параметризованный конструктор внутри своего абстрактного класса, почему не будет работать расширение для другого класса, если я не объявлю себя конструктором с ключевым словом super, вызывающим параметры конструктора абстрактного класса?»
Я понимаю тот факт, что расширение экземпляров предыдущего абстрактного класса в расширенный и пытается вызвать конструктор по умолчанию, но мне было интересно, почему он выдает ошибку.
Это потому, что конструктор был параметризован или просто потому, что пустой конструктор не существует?
Вызывает ли ключевое слово расширяет что-то вроде этого?
Object myClass = new AbstractClass();
И отсутствующие параметры являются причиной того, что он выдает ошибку, поэтому что-то вроде этого было бы правильным
Object myClass = new AbstractClass(int foo,float boo);
И если это так, ключевое слово super по существу, если вы позволите мне термин, «помещает» параметры, указанные в скобках, «внутри» конструктора?
Если это не так, что я получаю неправильно? Как работает фактически?
Вы в значительной степени поняли это. Хотя дело не столько в ключевое слово расширения, сколько в том, что ваш класс является подклассом другого класса. Ключевое слово extends используется в других ситуациях, кроме расширения класса, и в этом случае оно не делает всего того, что вы здесь обсуждали. Быть подклассом делает их.
Хорошо, я понимаю! большое спасибо! Итак, с расширениями я говорю моему подклассу наследовать атрибуты, конструкторы и методы абстрактного класса?
Мне кажется, это хороший способ думать об этом. С несколько иной точки зрения вы можете думать об этом так: когда вы объявляете класс с одним конструктором, который принимает один или несколько параметров, вы «говорите» компилятору, что эти параметры необходимы для существования любого экземпляра класса. Foo. Поскольку экземпляр класса, который расширяет Foo, по сути, также является экземпляром Foo, то любые экземпляры расширяющего класса также должны требовать одни и те же параметры, хотя они могут быть предоставлены расширяющим классом, а не обязательно тем, кто создает этот объект.
Я не понимаю вопрос Does the extends keyword call something along the lines of this? с примером Object myClass = new AbstractClass();. Не могли бы вы рассказать немного больше здесь?
@lealceldeiro я имел в виду, когда делал это public class myClass extends AbstractClass это в основном делает это Object myClass = new AbstractClass();




При инициализации объекта всегда будет вызываться конструктор. Даже если вы не определите один конструктор, будет конструктор по умолчанию без каких-либо параметров. Поэтому, если вы определяете конструктор в абстрактном классе, вы должны вызывать этот конструктор с помощью super().
Если вы не определяете никаких конструкторов, то он будет неявно вызываться как конструктор по умолчанию.
"If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?"
Потому что суперкласс говорит, что он ДОЛЖЕН быть конструктором, использующим этот объявленный конструктор, и другого пути нет. Это относится к каждому расширяющемуся классу - должен быть вызван требуемый конструктор.
То же самое происходит с любым классом, когда вы объявляете конструктор, отличный от конструктора по умолчанию. Например, имея
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. Поскольку конструктора по умолчанию нет, необходимо использовать ЛЮБОЙ явно объявленный суперконструктор.
Вы должны думать о ключевом слове 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() явный с параметром.
If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?
В 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();
Если ваш класс абстрактный, вы не можете создать его экземпляр с помощью ключевого слова
new.