Javaでの継承の例

Javaの継承は、オブジェクト指向プログラミングの中核的な概念の1つです。Javaの継承は、オブジェクト間にis-aの関係がある場合に使用されます。Javaの継承は、extendsキーワードを使用して実装されます。

Javaの継承

Javaの継承は、他のクラスから継承することによってクラス間の階層を作成する方法です。

Javaの継承は推移的です – つまり、SedanがCarを拡張し、CarがVehicleを拡張している場合、SedanはVehicleクラスからも継承されます。VehicleはCarとSedanのスーパークラスとなります。

継承は、例えば例外クラスを拡張してエラーコードなどの追加情報を含むアプリケーション固有の例外クラスを作成するために、Javaアプリケーションで広く使用されています。例えばNullPointerExceptionです。

Javaの継承の例

Javaのすべてのクラスは、暗黙的にjava.lang.Objectクラスを拡張します。そのため、ObjectクラスはJavaの継承階層の最上位にあります。

では、簡単な例を使ってJavaでの継承の実装方法を見てみましょう。

スーパークラス:Animal

package com.journaldev.inheritance;

public class Animal {

	private boolean vegetarian;

	private String eats;

	private int noOfLegs;

	public Animal(){}

	public Animal(boolean veg, String food, int legs){
		this.vegetarian = veg;
		this.eats = food;
		this.noOfLegs = legs;
	}

	public boolean isVegetarian() {
		return vegetarian;
	}

	public void setVegetarian(boolean vegetarian) {
		this.vegetarian = vegetarian;
	}

	public String getEats() {
		return eats;
	}

	public void setEats(String eats) {
		this.eats = eats;
	}

	public int getNoOfLegs() {
		return noOfLegs;
	}

	public void setNoOfLegs(int noOfLegs) {
		this.noOfLegs = noOfLegs;
	}

}

動物はここでベースクラスです。Animalクラスから継承するCatクラスを作成しましょう。

サブクラス: Cat

package com.journaldev.inheritance;

public class Cat extends Animal{

	private String color;

	public Cat(boolean veg, String food, int legs) {
		super(veg, food, legs);
		this.color="White";
	}

	public Cat(boolean veg, String food, int legs, String color){
		super(veg, food, legs);
		this.color=color;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

}

Javaでは継承を実装するためにextendsキーワードを使用していることに注意してください。

Java継承テストプログラム

簡単なテストクラスを書いて、Catオブジェクトを作成し、そのいくつかのメソッドを使用しましょう。

package com.journaldev.inheritance;

public class AnimalInheritanceTest {

	public static void main(String[] args) {
		Cat cat = new Cat(false, "milk", 4, "black");

		System.out.println("Cat is Vegetarian?" + cat.isVegetarian());
		System.out.println("Cat eats " + cat.getEats());
		System.out.println("Cat has " + cat.getNoOfLegs() + " legs.");
		System.out.println("Cat color is " + cat.getColor());
	}

}

出力:

CatクラスにはgetEats()メソッドがありませんが、プログラムは動作します。なぜなら、それがAnimalクラスから継承されているからです。

重要なポイント

  1. コード再利用は継承の最も重要な利点です。サブクラスはスーパークラスの変数とメソッドを継承します。

  2. スーパークラスのプライベートメンバーはサブクラスから直接アクセスできません。この例では、Animal変数のnoOfLegsはCatクラスから直接アクセスできませんが、getterおよびsetterメソッドを介して間接的にアクセスできます。

  3. デフォルトのアクセスを持つスーパークラスのメンバーは、同じパッケージ内にある場合にのみサブクラスからアクセスできます。

  4. スーパークラスのコンストラクタは、サブクラスによって継承されません。

  5. スーパークラスにデフォルトコンストラクタがない場合、サブクラスも明示的なコンストラクタを定義する必要があります。そうしないと、コンパイル時例外がスローされます。サブクラスのコンストラクタでは、この場合、スーパークラスのコンストラクタを呼び出すことが義務付けられており、サブクラスのコンストラクタ内の最初のステートメントである必要があります。

  6. Javaは複数の継承をサポートしていません、サブクラスは1つのクラスのみを拡張できます。Animalクラスは暗黙的にObjectクラスを拡張しており、CatクラスもAnimalクラスを拡張していますが、Javaの継承の推移的な性質のため、CatクラスもObjectクラスを拡張しています。

  7. サブクラスのインスタンスを作成し、それをスーパークラスの変数に割り当てることができます。これをアップキャストと呼びます。以下はアップキャストの単純な例です:

    Cat c = new Cat(); //サブクラスのインスタンス
    Animal a = c; //アップキャスト、CatもAnimalなので問題ありません
    
  8. スーパークラスのインスタンスがサブクラス変数に割り当てられると、それをダウンキャストと呼びます。これをサブクラスに明示的にキャストする必要があります。例;

    Cat c = new Cat();
    Animal a = c;
    Cat c1 = (Cat) a; //明示的なキャスティング、"c"は実際にCat型ですので正常に動作します
    

    コンパイラは明示的なキャスティングのため、間違っていても文句を言いません。以下は、実行時にClassCastExceptionをスローする場合のいくつかのケースです。

    Dog d = new Dog();
    Animal a = d;
    Cat c1 = (Cat) a; //実行時にClassCastException
    
    Animal a1 = new Animal();
    Cat c2 = (Cat) a1; //実行時にa1は実際にAnimal型であるためClassCastExceptionがスローされます
    
  9. サブクラスではスーパークラスのメソッドをオーバーライドできます。ただし、常にオーバーライドされたメソッドには@Overrideアノテーションを付ける必要があります。コンパイラはメソッドがオーバーライドされていることを知り、スーパークラスのメソッドに何か変更があれば、実行時の望ましくない結果ではなく、コンパイル時エラーを取得します。

  10. スーパークラスのメソッドを呼び出したり、スーパークラスの変数にアクセスしたりするには、superキーワードを使用することができます。これは、サブクラスに同じ名前の変数/メソッドがあるが、スーパークラスの変数/メソッドにアクセスしたい場合に便利です。これはまた、スーパークラスとサブクラスの両方にコンストラクタが定義されている場合や、明示的にスーパークラスのコンストラクタを呼び出す必要がある場合にも使用されます。

  11. オブジェクト間の継承をチェックするために、instanceof命令を使用することができます。以下の例を見てみましょう。

```
Cat c = new Cat();
Dog d = new Dog();
Animal an = c;

boolean flag = c instanceof Cat; //normal case, returns true

flag = c instanceof Animal; // returns true since c is-an Animal too

flag = an instanceof Cat; //returns true because a is of type Cat at runtime

flag = an instanceof Dog; //returns false for obvious reasons.
```
  1. Javaでは、finalクラスを継承することはできません。
  2. もしコードでSuperclassを使用しない場合、つまりあなたのSuperclassが再利用可能なコードを保持するための基本だけである場合は、クライアントクラスによる不必要なインスタンス化を避けるために抽象クラスとしてそれらを保持することができます。これにより、ベースクラスのインスタンス作成も制限されます。

Java継承ビデオチュートリアル

I have recently published two videos on YouTube explaining Inheritance in detail with sample programs, you should watch them below.


より多くの継承の例は、私たちのGitHubリポジトリからチェックアウトできます。

参考:Oracleドキュメント

Source:
https://www.digitalocean.com/community/tutorials/inheritance-java-example