Почему нельзя использовать this()
и super()
вместе в конструкторе?
В чем причина включения такой вещи?
Почему нельзя использовать this()
и super()
вместе в конструкторе?
В чем причина включения такой вещи?
this(...)
вызовет другой конструктор в том же классе, тогда как super()
вызовет супер-конструктор. Если в конструкторе нет super()
, компилятор добавит его неявно.
Таким образом, если бы оба были разрешены, вы могли бы дважды вызвать конструктор super
.
Пример (не искать смысла в параметрах):
class A {
public A() {
this( false );
}
public A(boolean someFlag) {
}
}
class B extends A {
public B() {
super();
}
public B( boolean someFlag ) {
super( someFlag );
}
public B ( int someNumber ) {
this(); //
}
}
Теперь, если вы вызываете new B(5)
, вызываются следующие конструкторы:
this( false);
A() ---------------> A(false)
^
|
| super();
|
| this();
B() <--------------- B(5) <--- you start here
Update:
Если вы могли использовать this()
и super()
, вы могли бы получить что-то вроде этого:
( Внимание: это означает показать, что может пойти не так, если вам разрешили это сделать - к счастью, это не так)
this( false);
A() ---------------> A(false)
^ ^
| |
| super(); | super( true ); <--- Problem: should the parameter be true or false?
| |
| this(); |
B() <--------------- B(5) <--- you start here
Как вы можете видеть, вы столкнулись с проблемой, при которой конструктор A(boolean)
мог бы вызываться с разными параметрами, и вам теперь нужно как-то решить, какой из них следует использовать. Кроме того, другие конструкторы (A()
и B()
) могут содержать код, который теперь не может быть вызван правильно (т.е. Из-за порядка и т.д.), Поскольку вызов super( true )
обойдет их, а this()
не будет.
Существует разница между super()
и this()
.
super()
- вызывает конструктор базового класса, тогда как
this()
- вызывает текущий конструктор классов.
Оба this()
и super()
являются вызовами конструктора.
Конструкторский вызов всегда должен быть первым выражением. Таким образом, мы не можем иметь два оператора в качестве первого оператора, поэтому мы можем вызывать super()
или мы можем вызвать this()
из конструктора, но не оба.
Оба this()
и super()
являются вызовами конструктора, а вызов конструктора должен быть первым (и только первым) вызовом в конструкторе. В противном случае конструктор Object
будет вызываться более одного раза при создании экземпляра одного объекта.
И есть условие в том, что они должны быть объявлены в первой строке конструктора, который вы используете. И это причина, по которой мы не можем использовать оба в одном конструкторе, потому что вы можете написать только одну вещь в своей первой строке.
Потому что это не имеет смысла. Конструктор должен либо вызывать this()
, либо super()
(неявно или явно). this()
вызывает другой конструктор, который должен вызывать либо this()
, либо super()
и т.д., как и раньше. Следовательно, конструктор, который вызывал как this()
, так и super()
, в конечном итоге вызывал super()
дважды.
Сравните пример ниже. Класс FirstChild устанавливает имя переменной экземпляра в 2 конструкторах, поскольку вызов второго конструктора из первого исключается из-за необходимости вызова super().
В классе SecondChild представлен третий частный конструктор, который принимает 2 параметра - сначала один передан в supper(), а второй - для установки имени. Первые 2 конструктора называют третий. Супер() вызывается ровно один раз, также переменная экземпляра задается только в одном конструкторе. Код дает тот же результат без вызова super() и this() в том же конструкторе.
class FirstChild extends ConstructorTest{
private String name = null;
public FirstChild(){
super("super text 1");
//this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
name = "Unknown";
}
public FirstChild(String name){
super("super text 2");
this.name = name;
}
public String getName(){
return name;
}
}
class SecondChild extends ConstructorTest{
private String name = null;
public SecondChild(){
this("super text 1", "Unknown");
}
public SecondChild(String name){
this("super text 2", name);
}
private SecondChild(String superStr, String name)
{
super(superStr);
this.name = name;
}
public String getName(){
return name;
}
}
public class ConstructorTest{
public ConstructorTest(String str){
System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
}
public static void main(String... args)
{
System.out.println("Hello from main, FirstChild results:");
FirstChild fc1 = new FirstChild();
FirstChild fc2 = new FirstChild("John");
System.out.println(" child fc1 name: " + fc1.getName());
System.out.println(" child fc2 name: " + fc2.getName());
System.out.println("Hello from main, SecondChild results:");
SecondChild sc1 = new SecondChild();
SecondChild sc2 = new SecondChild("John");
System.out.println(" child sc1 name: " + sc1.getName());
System.out.println(" child sc2 name: " + sc2.getName());
}
}
Потому что, если вы используете this()
и super()
вместе в конструкторе, он даст ошибку времени компиляции. Потому что this()
и super()
должны быть первым исполняемым оператором. Если вы напишете this()
сначала, чем super()
, станет вторым утверждением и наоборот. Поэтому мы не можем использовать this()
и super()
вместе.
this() и super(), оба являются конструкторами, которые должны быть первым утверждением. Но мы можем использовать оба в программе.
this(): он используется для вызова того же класса Default или Parametrized Constructor.
super(): он используется для вызова немедленного супер/родительского класса. По умолчанию или параметризованный конструктор.
//Super Class
public class SuperConstructor {
SuperConstructor(){
this(10);
System.out.println("Super DC");
}
SuperConstructor(int a){
this(10,20);
System.out.println("Suer SPC with Iteger");
}
SuperConstructor(int i,int j){
System.out.println("Super with DPC with Iteger and Integer");
}
}
//subclass
public class ThisConstructor extends SuperConstructor{
ThisConstructor(){
this(10,20);
System.out.println("Subcalss DC ");//DC Default Constructor
}
ThisConstructor(int i){
super(i);
System.out.println("Subcalss SPC with Iteger");//SPC Single Parameterized Constructor
}
ThisConstructor(int i, String s){
this();
System.out.println("Subcalss DPC with Iteger and String");//DPC double Parameterized Constructor
}
ThisConstructor(int i,int age){
super(i,age);
System.out.println("Subcalss DPC with Iteger and Integer");
}
public static void main(String []k){
System.out.println("=================Frist time Calling ==========================\n");
ThisConstructor t = new ThisConstructor(1);
System.out.println("=================Second time Calling ==========================\n");
ThisConstructor t1 = new ThisConstructor(1,2);
}
}