はじめに
この実験では、Java におけるオブジェクト指向プログラミングの 2 つの基本概念である継承とポリモーフィズムを探ります。これらの強力な機能により、より組織的で効率的で柔軟なコードを作成することができます。まずは継承を探り、既存のクラスを基に新しいクラスを作成することができるようになり、次にポリモーフィズムに移り、異なるクラスのオブジェクトを統一的に扱うことができるようになります。
この実験が終了すると、以下のことができるようになります。
- 継承を使ってクラス階層を作成する
- サブクラスでメソッドをオーバーライドする
- ポリモーフィズムを理解して使用する
- 抽象クラスと抽象メソッドを実装する
これらの用語が複雑に聞こえる場合は心配しないでください。すべてを簡単で分かりやすい手順に分解します。Java プログラミングスキルを向上させる刺激的な旅に始めましょう!
基底クラスの作成
まずは、Animal という名前の基底クラスを作成します。このクラスは他のクラスの基礎となります。
ターミナルを開き、プロジェクトディレクトリに移動します。
cd ~/projecttouchコマンドを使って、Animal.javaという新しいファイルを作成します。touch Animal.javaテキストエディタで
Animal.javaを開き、次のコードを追加します。public class Animal { private String name; private int age; public Animal(String name, int age) { this.name = name; this.age = age; } public void eat() { System.out.println(name + " is eating."); } public void sleep() { System.out.println(name + " is sleeping."); } public String getName() { return name; } public int getAge() { return age; } }このコードを分解してみましょう。
Animalという名前のクラスを定義し、2 つの属性name(文字列型)とage(整数型)を持ちます。privateキーワードは、これらの属性がクラス内でのみアクセス可能であることを意味します。Animalオブジェクトが作成されるときにこれらの属性を初期化するコンストラクタがあります。eat()とsleep()の 2 つのメソッドがあり、動物が何をしているかを表示します。- クラスの外から private 属性にアクセスできるようにする "getter" メソッド (
getName()とgetAge()) もあります。
Animal.javaファイルを保存します。

次に、
Animalクラスをコンパイルしてエラーがないことを確認しましょう。ターミナルで次のコマンドを実行します。javac Animal.javaエラーメッセージがなければ、クラスのコンパイルは成功です!
サブクラスの作成
基本クラスである Animal ができたので、Dog というサブクラスを作成してみましょう。これにより、Java における継承の仕組みを説明します。
ターミナルで、
Dog.javaという新しいファイルを作成します。touch Dog.javaテキストエディタで
Dog.javaを開き、以下のコードを追加します。public class Dog extends Animal { private String breed; public Dog(String name, int age, String breed) { super(name, age); // スーパークラスのコンストラクタを呼び出す this.breed = breed; } public String getBreed() { return breed; } }この新しいコードを詳しく見ていきましょう。
extends Animalは、DogがAnimalのサブクラスであることを Java に伝えます。DogはAnimalから継承しますが、Animalのプライベート属性であるnameとageは、Dog内で直接アクセスすることはできません。しかし、Dogは継承されたパブリックな getter メソッドであるgetName()とgetAge()を介してこれらの属性にアクセスできます。Dogに固有の新しい属性breedを追加しました。- コンストラクタは 3 つのパラメータを取ります。
super(name, age)を使用してAnimalコンストラクタを呼び出し、次にbreedを設定します。 Dogに固有の新しいメソッドgetBreed()を追加しました。
Dog.javaファイルを保存します。Dogクラスをコンパイルします。javac Dog.javaAnimal.classに関する警告が表示されるかもしれませんが、今のところ問題ありません。
継承の示す
Animal クラスと Dog クラスができたので、継承がどのように機能するかを示すプログラムを作成しましょう。
InheritanceDemo.javaという新しいファイルを作成します。touch InheritanceDemo.javaInheritanceDemo.javaを開き、次のコードを追加します。public class InheritanceDemo { public static void main(String[] args) { Animal genericAnimal = new Animal("Generic Animal", 5); Dog myDog = new Dog("Buddy", 3, "Labrador"); System.out.println("Demonstrating Animal class:"); genericAnimal.eat(); genericAnimal.sleep(); System.out.println("\nDemonstrating Dog class:"); myDog.eat(); // Animalから継承 myDog.sleep(); // Animalから継承 System.out.println("\nDog details:"); System.out.println("Name: " + myDog.getName()); // 継承されたメソッド System.out.println("Age: " + myDog.getAge()); // 継承されたメソッド System.out.println("Breed: " + myDog.getBreed()); // Dog固有のメソッド } }このプログラムは、
AnimalクラスとDogクラスの両方のインスタンスを作成し、DogクラスがAnimalクラスからメソッドを継承する方法を示しています。InheritanceDemo.javaファイルを保存します。プログラムをコンパイルして実行します。
javac InheritanceDemo.java java InheritanceDemo次のような出力が表示されるはずです。
Demonstrating Animal class: Generic Animal is eating. Generic Animal is sleeping. Demonstrating Dog class: Buddy is eating. Buddy is sleeping. Dog details: Name: Buddy Age: 3 Breed: Labrador
この実証は、Dog クラスが Animal クラスから属性とメソッドを継承する一方で、独自の固有の属性 (breed) とメソッド (getBreed()) を追加する方法を示しています。
メソッドのオーバーライド
メソッドのオーバーライドは、サブクラスがスーパークラスに既に定義されているメソッドの特定の実装を提供できる機能です。これがどのように機能するか見てみましょう。
Dog.javaを開き、次のメソッドを追加します。@Override public void eat() { System.out.println(getName() + " is eating dog food."); }このメソッドを
Dogクラスの内部で、他のメソッドの外に追加します。@Overrideアノテーションは、コンパイラに対して、スーパークラスのメソッドをオーバーライドすることを意図していることを伝えます。必須ではありませんが、使用するのは良い慣例です。Dog.javaファイルを保存します。次に、メソッドのオーバーライドを示すために
InheritanceDemo.javaを変更しましょう。InheritanceDemo.javaを開き、その内容を次のものに置き換えます。public class InheritanceDemo { public static void main(String[] args) { Animal genericAnimal = new Animal("Generic Animal", 5); Dog myDog = new Dog("Buddy", 3, "Labrador"); System.out.println("Demonstrating method overriding:"); genericAnimal.eat(); myDog.eat(); System.out.println("\nDemonstrating inherited method:"); myDog.sleep(); // このメソッドは依然としてAnimalから継承されています System.out.println("\nDog details:"); System.out.println("Name: " + myDog.getName()); System.out.println("Age: " + myDog.getAge()); System.out.println("Breed: " + myDog.getBreed()); } }InheritanceDemo.javaファイルを保存します。更新されたプログラムをコンパイルして実行します。
javac Animal.java Dog.java InheritanceDemo.java java InheritanceDemo

次のような出力が表示されるはずです。
Demonstrating method overriding:
Generic Animal is eating.
Buddy is eating dog food.
Demonstrating inherited method:
Buddy is sleeping.
Dog details:
Name: Buddy
Age: 3
Breed: Labrador
これは、メソッドのオーバーライドが Dog クラスに eat() メソッドの独自の実装を提供する一方で、Animal クラスから sleep() のような他のメソッドを継承し続ける方法を示しています。
ポリモーフィズムの紹介
ポリモーフィズムはオブジェクト指向プログラミングにおける基本的な概念で、基底クラスの参照を使ってサブクラスのオブジェクトを参照できるようにします。これにより、より柔軟で再利用可能なコードが可能になります。どのように機能するか見てみましょう。
Cat.javaという新しいファイルを作成します。touch Cat.javaCat.javaを開き、次のコードを追加します。public class Cat extends Animal { public Cat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println(getName() + " is eating fish."); } public void meow() { System.out.println(getName() + " says: Meow!"); } }これは、独自の
eat()メソッドと新しいmeow()メソッドを持つAnimalの別のサブクラスを作成します。Cat.javaファイルを保存します。次に、ポリモーフィズムを示すために
InheritanceDemo.javaを更新しましょう。その内容を次のものに置き換えます。public class InheritanceDemo { public static void main(String[] args) { Animal[] animals = new Animal[3]; animals[0] = new Animal("Generic Animal", 5); animals[1] = new Dog("Buddy", 3, "Labrador"); animals[2] = new Cat("Whiskers", 2); System.out.println("Demonstrating polymorphism:"); for (Animal animal : animals) { animal.eat(); // これは各動物に適切なeat()メソッドを呼び出します } System.out.println("\nAccessing specific methods:"); ((Dog) animals[1]).getBreed(); // Dog固有のメソッドを呼び出すにはDogにキャストする必要があります ((Cat) animals[2]).meow(); // Cat固有のメソッドを呼び出すにはCatにキャストする必要があります } }このコードは
Animalオブジェクトの配列を作成しますが、実際にはその中にAnimal、Dog、Catのオブジェクトの混合物を格納しています。各動物に対してeat()を呼び出すと、Java はオブジェクトの実際の型に基づいて適切なメソッドのバージョンを自動的に呼び出します。InheritanceDemo.javaファイルを保存します。更新されたプログラムをコンパイルして実行します。
javac Animal.java Dog.java Cat.java InheritanceDemo.java java InheritanceDemo次のような出力が表示されるはずです。
Demonstrating polymorphism: Generic Animal is eating. Buddy is eating dog food. Whiskers is eating fish. Accessing specific methods: Whiskers says: Meow!
これはポリモーフィズムの実際の動作を示しています。すべてのオブジェクトを Animal オブジェクトとして扱うことができますが、eat() メソッドを呼び出すと、各オブジェクトはその特定のクラスの実装に従って動作します。
まとめ
この実験では、Java におけるオブジェクト指向プログラミングのいくつかの重要な概念を探りました。
- 継承:基底の
Animalクラスを作成し、それからDogクラスとCatクラスを派生させました。これにより、コードの再利用が可能になり、クラスの論理的な階層構造を作成できました。 - メソッドのオーバーライド:サブクラスがスーパークラスに定義されたメソッドの独自の実装を提供できる方法を見ました。これにより、より具体的な動作が可能になります。
- ポリモーフィズム:異なるクラスのオブジェクトをそれらの共通のスーパークラスを通じて一様に扱う方法を学びました。これにより、より柔軟で再利用可能なコードが可能になります。
これらの概念は、Java や一般的なオブジェクト指向プログラミングにとって基本的なものです。これらを使うことで、より組織的で効率的で柔軟なコード構造を作成できます。Java の学習を続けるにつれて、これらの概念がより複雑なアプリケーションで広く使用されていることに気付くでしょう。
覚えておいてください。これらの概念をマスターするキーは練習です。



