JavaRush /Java Blog /Random-JA /基本クラスのコンストラクター

基本クラスのコンストラクター

Random-JA グループに公開済み
こんにちは!前回はコンストラクターについて説明し、コンストラクターについて多くのことを学びました。ここで、基底クラスのコンストラクターなどについて説明します。基本クラスとは何ですか? 実際、Java では、いくつかの異なるクラスが共通の起源を持つことができます。 基本クラスのコンストラクター - 2これを継承と呼びます。複数の子孫クラスが 1 つの共通の祖先クラスを持つことができます。たとえば、クラスAnimal(動物) があると想像してください。
public class Animal {

   String name;
   int age;
}
たとえば、 2 つの子孫クラス (Catと )を作成できますDog。これは、キーワード を使用して行われますextends
public class Cat extends Animal {

}

public class Dog extends Animal {

}
これは将来的に役立つかもしれません。たとえば、タスクがネズミを捕まえることである場合、プログラム内にオブジェクトを作成しますCat。タスクがスティックの後に実行される場合は、 オブジェクト を使用しますDog。そして、動物病院をシミュレートするプログラムを作成すると、クラスと連携して動作しますAnimal(犬と猫の両方を治療できるようになります)。将来のために、オブジェクトを作成するときは、その基本クラスのコンストラクターが最初に呼び出され、その後、作成しているオブジェクトであるクラス自体のコンストラクターが呼び出されるということを覚えておくことが非常に重要です。つまり、オブジェクトを作成するときは、Catクラス コンストラクターが最初に機能しAnimal、次にコンストラクターが機能しますCat。これを確認するために、コンストラクターを追加してCatコンソールAnimalに出力しましょう。
public class Animal {

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


public class Cat extends Animal {

   public Cat() {
       System.out.println("The constructor Cat worked!");
   }

   public static void main(String[] args) {
       Cat cat = new Cat();
   }
}
コンソール出力:

Отработал конструктор Animal
Отработал конструктор Cat!
確かに、これがすべての仕組みです。それはなんのためですか?たとえば、2 つのクラスの共通フィールドの重複を避けるためです。たとえば、すべての動物には心臓と脳がありますが、すべての動物に尻尾があるわけではありません。すべての動物に共通のフィールドを親クラスbrainで宣言し、フィールドをサブクラスで宣言できます。次に、 class のコンストラクターを作成し、3 つのフィールドすべてを渡します。 heartAnimaltailCatCat
public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
注意してください:クラスにはフィールドと がCatありませんが、コンストラクターは正常に機能します。これらのフィールドは、基本クラスから「プルアップ」されました。子孫クラスは基本クラスのフィールドにアクセスできるため、それらのフィールドはクラス内で表示されます。したがって、クラス内でこれらのフィールドを複製する必要はありません。クラスから取得できます。さらに、子孫クラスのコンストラクター内で基本クラスのコンストラクターを明示的に呼び出すことができます。基本クラスは「スーパークラス」とも呼ばれ、Java がこのキーワードを使用するのはこのためです。前の例では brainheartAnimalCatCatAnimalsuper
public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
親クラスの各フィールドを個別に割り当てました。実際には、これを行う必要はありません。親クラスのコンストラクターを呼び出して、必要なパラメーターを渡すだけで十分です。
public class Animal {

   String brain;
   String heart;

   public Animal(String brain, String heart) {
       this.brain = brain;
       this.heart = heart;
   }

public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       this.tail = tail;
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
コンストラクターでは、Catコンストラクターを呼び出しAnimal、2 つのフィールドをコンストラクターに渡しました。明示的に初期化する必要があるのは 1 つのフィールドだけです (存在しtailませAnimalん)。オブジェクトが作成されるときに、親クラスのコンストラクターが最初に呼び出されるという話を覚えていますか? したがって、単語がsuper()コンストラクター内で常に最初に来る必要があるのはこのためです。そうしないと、コンストラクターのロジックが壊れ、プログラムでエラーが生成されます。
public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.tail = tail;
       super(brain, heart);//error!
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
コンパイラは、子孫クラスのオブジェクトを作成するときに、基本クラスのコンストラクターが最初に呼び出されることを認識しています。この動作を手動で変更しようとしても、変更は許可されません。

オブジェクトを作成するプロセス。

Animal上では、基本クラスと親クラス、およびを使用した例を見てきましたCat。ここで、これら 2 つのクラスを例として使用して、オブジェクトの作成と変数の初期化のプロセスを見ていきます。変数には静的変数とインスタンス変数(非静的変数)があることがわかっています。また、基本クラスにはAnimal独自の変数があり、子孫クラスにCatは独自の変数があることもわかります。AnimalわかりやすくするCatために、クラスに静的変数を 1 つ追加しましょう。animalCountクラス変数はAnimal地球上の動物種の総数、変数はcatsCount猫の種の数になります。さらに、両方のクラスのすべての非静的変数に開始値を割り当てます (その後、コンストラクターで変更されます)。
public class Animal {

   String brain = "The initial value of brain in the Animal class";
   String heart = "The initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("The constructor of the Animal base class is being executed");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("The current value of the static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in class Animal = " + this.brain);
       System.out.println("Current value of heart in class Animal = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("The current value of the static variable catsCount = " + Cat.catsCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor completed!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "The initial value of tail in the Cat class";

   static int catsCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The constructor of the Cat class has started (the Animal constructor has already been executed)");
       System.out.println("The current value of the static variable catsCount = " + catsCount);
       System.out.println("Current value tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
Catそこで、から継承した クラスの新しいオブジェクトを作成しますAnimal。詳細なコンソール出力をプログラムに追加して、何がどのような順序で起こるかを見てみましょう。これは、オブジェクトを作成した結果としてコンソールに出力されるものですCat

Выполняется конструктор базового класса Animal
Были ли уже проинициализированы переменные класса Animal?
Текущее meaning статической переменной animalCount = 7700000
Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal
Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
Были ли уже проинициализированы переменные класса Cat?
Текущее meaning статической переменной catsCount = 37
Конструктор базового класса Animal завершил работу!
Текущее meaning brain = Мозг
Текущее meaning heart = Сердце
Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
Текущее meaning статической переменной catsCount = 37
Текущее meaning tail = Изначальное meaning tail в классе Cat
Текущее meaning tail = Хвост
これで、新しいオブジェクトの作成時に変数が初期化され、コンストラクターが呼び出される順序が明確にわかります。
  1. 基本クラス( ) の静的変数が初期化されます。この例では、クラス変数には値 7700000 が割り当てられます。AnimalanimalCountAnimal

  2. 子孫クラス( ) の静的変数が初期化されます。注意してください - 私たちはまだコンストラクター内にいますが、コンソールにはすでに次のように表示されています。CatAnimal

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее meaning статической переменной animalCount = 7700000
        Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal
        Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
        Были ли уже проинициализированы переменные класса Cat?
        Текущее meaning статической переменной catsCount = 37
  3. 次に、基本クラスの非静的変数が初期化されます。具体的には初期値を割り当て、コンストラクターで新しい値に変更します。コンストラクターはまだ作業を完了していませんが、初期値はすでに割り当てられています。Animalbrainheart

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее meaning статической переменной animalCount = 7700000
        Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal
        Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
  4. 基本クラスのコンストラクターが動作を開始します。

    このステージは連続して 4 番目にすぎないことはすでに確認しました。最初の 3 つのポイントでは、コンストラクターが動作を開始する時点で、Animal多くの変数にすでに値が割り当てられています。

  5. 子クラスの非静的フィールドを初期化しています( )。Cat

    それはデザイナーがCat仕事を始める前に起こります。

    彼が仕事を始めた時点では、変数にtailはすでに値が含まれていました。

    
    Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
    Текущее meaning статической переменной catsCount = 37
    Текущее meaning tail = Изначальное meaning tail в классе Cat
  6. 子孫クラスのコンストラクターが呼び出されます。 Cat

Java でオブジェクトを作成するプロセスは次のようになります。私たちは詰め込みの大ファンではないと言わなければなりませんが、変数の初期化とコンストラクターの呼び出しの順序を覚えて、将来のために覚えておくことをお勧めします。これにより、プログラムの進行状況やその時点でのオブジェクトの状態についての理解が大幅に深まります。さらに、クラスには直接の親クラス (スーパークラス/基本クラス) がないことがよくあります。この場合、基本クラスに関連付けられた項目は実行されません。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION