Java継承完全ガイド: extends・super・IS-A関係・多重継承の制約
継承とは、あるクラスが別のクラスのプロパティ(メソッドとフィールド)を取得するプロセスと定義できます。継承を使用することで、情報が階層的な順序で管理しやすくなります。
他のクラスのプロパティを継承するクラスをサブクラス(派生クラス、子クラス)と呼び、そのプロパティが継承されるクラスをスーパークラス(基底クラス、親クラス)と呼びます。
extendsキーワード
extendsはクラスのプロパティを継承するために使用するキーワードです。extendsキーワードの構文は以下の通りです。
構文
class Super {
.....
.....
}
class Sub extends Super {
.....
.....
}
サンプルコード
Java継承を示す例です。この例ではCalculationとMy_Calculationという2つのクラスがあります。
extendsキーワードを使用して、My_CalculationはCalculationクラスのaddition()とSubtraction()メソッドを継承します。
以下のプログラムをMy_Calculation.javaという名前のファイルにコピー&ペーストしてください。
例
class Calculation {
int z;
public void addition(int x, int y) {
z = x + y;
System.out.println("The sum of the given numbers:" + z);
}
public void Subtraction(int x, int y) {
z = x - y;
System.out.println("The difference between the given numbers:" + z);
}
}
public class My_Calculation extends Calculation {
public void multiplication(int x, int y) {
z = x * y;
System.out.println("The product of the given numbers:" + z);
}
public static void main(String args[]) {
int a = 20, b = 10;
My_Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);
demo.multiplication(a, b);
}
}
以下のようにコンパイル・実行します。
javac My_Calculation.java
java My_Calculation
プログラムを実行すると以下の結果が得られます。
出力
The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200
このプログラムでは、My_Calculationクラスのオブジェクトが作成されると、スーパークラスの内容のコピーがその中に作成されます。そのため、サブクラスのオブジェクトを使用してスーパークラスのメンバにアクセスできます。
スーパークラスの参照変数はサブクラスのオブジェクトを保持できますが、その変数を使用してアクセスできるのはスーパークラスのメンバのみです。したがって、両方のクラスのメンバにアクセスするには、常にサブクラスへの参照変数を作成することをお勧めします。
上記プログラムを考慮すると、以下のようにクラスをインスタンス化できます。しかし、スーパークラスの参照変数(この場合はcal)を使用して、サブクラスMy_Calculationに属するmultiplication()メソッドを呼び出すことはできません。
Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);
注意 - サブクラスはスーパークラスのすべてのメンバ(フィールド、メソッド、ネストクラス)を継承します。コンストラクタはメンバではないためサブクラスに継承されませんが、スーパークラスのコンストラクタはサブクラスから呼び出せます。
superキーワード
superキーワードはthisキーワードに似ています。superキーワードが使用されるシナリオは以下の通りです。
- スーパークラスのメンバとサブクラスのメンバが同じ名前の場合、それらを区別するために使用
- サブクラスからスーパークラスのコンストラクタを呼び出すために使用
メンバの区別
あるクラスが別のクラスのプロパティを継承している場合、スーパークラスのメンバがサブクラスと同じ名前を持つことがあります。これらの変数を区別するためにsuperキーワードを以下のように使用します。
super.variable
super.method();
サンプルコード
このセクションではsuperキーワードの使用法を示すプログラムを提供します。
与えられたプログラムにはSub_classとSuper_classという2つのクラスがあり、両方に異なる実装のdisplay()メソッドと、異なる値を持つnumという変数があります。両クラスのdisplay()メソッドを呼び出し、両クラスのnum変数の値を出力します。ここでsuperキーワードを使用してスーパークラスのメンバとサブクラスのメンバを区別しています。
プログラムをSub_class.javaという名前のファイルにコピー&ペーストしてください。
例
class Super_class {
int num = 20;
// スーパークラスのdisplayメソッド
public void display() {
System.out.println("This is the display method of superclass");
}
}
public class Sub_class extends Super_class {
int num = 10;
// サブクラスのdisplayメソッド
public void display() {
System.out.println("This is the display method of subclass");
}
public void my_method() {
// サブクラスをインスタンス化
Sub_class sub = new Sub_class();
// サブクラスのdisplay()メソッドを呼び出し
sub.display();
// スーパークラスのdisplay()メソッドを呼び出し
super.display();
// サブクラスの変数numの値を出力
System.out.println("value of the variable named num in sub class:" + sub.num);
// スーパークラスの変数numの値を出力
System.out.println("value of the variable named num in super class:" + super.num);
}
public static void main(String args[]) {
Sub_class obj = new Sub_class();
obj.my_method();
}
}
以下の構文でコンパイル・実行します。
javac Super_Demo
java Super
プログラムを実行すると以下の結果が得られます。
出力
This is the display method of subclass
This is the display method of superclass
value of the variable named num in sub class:10
value of the variable named num in super class:20
スーパークラスコンストラクタの呼び出し
あるクラスが別のクラスのプロパティを継承している場合、サブクラスは自動的にスーパークラスのデフォルトコンストラクタを取得します。しかし、スーパークラスのパラメータ付きコンストラクタを呼び出したい場合は、以下のようにsuperキーワードを使用する必要があります。
super(values);
サンプルコード
このセクションのプログラムは、superキーワードを使用してスーパークラスのパラメータ付きコンストラクタを呼び出す方法を示します。このプログラムにはスーパークラスとサブクラスがあり、スーパークラスには整数値を受け取るパラメータ付きコンストラクタが含まれ、superキーワードを使用してスーパークラスのパラメータ付きコンストラクタを呼び出しています。
プログラムをSubclass.javaという名前のファイルにコピー&ペーストしてください。
例
class Superclass {
int age;
Superclass(int age) {
this.age = age;
}
public void getAge() {
System.out.println("The value of the variable named age in super class is: " + age);
}
}
public class Subclass extends Superclass {
Subclass(int age) {
super(age);
}
public static void main(String args[]) {
Subclass s = new Subclass(24);
s.getAge();
}
}
以下の構文でコンパイル・実行します。
javac Subclass
java Subclass
プログラムを実行すると以下の結果が得られます。
出力
The value of the variable named age in super class is: 24
IS-A関係
IS-Aは「このオブジェクトはあのオブジェクトの一種である」と言う方法です。extendsキーワードがどのように継承を達成するために使用されるか見てみましょう。
public class Animal {
}
public class Mammal extends Animal {
}
public class Reptile extends Animal {
}
public class Dog extends Mammal {
}
上記の例に基づくと、オブジェクト指向の用語では以下が真となります。
- AnimalはMammalクラスのスーパークラスである
- AnimalはReptileクラスのスーパークラスである
- MammalとReptileはAnimalクラスのサブクラスである
- DogはMammalとAnimal両方のサブクラスである
IS-A関係を考慮すると、以下のように言えます。
- Mammal IS-A Animal
- Reptile IS-A Animal
- Dog IS-A Mammal
- したがって:Dog IS-A Animalでもある
extendsキーワードの使用により、サブクラスはスーパークラスのprivateプロパティを除くすべてのプロパティを継承できます。
instanceof演算子を使用して、Mammalが実際にAnimalであることを確認できます。
例
class Animal {
}
class Mammal extends Animal {
}
class Reptile extends Animal {
}
public class Dog extends Mammal {
public static void main(String args[]) {
Animal a = new Animal();
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal);
System.out.println(d instanceof Mammal);
System.out.println(d instanceof Animal);
}
}
出力
true
true
true
extendsキーワードをよく理解したところで、implementsキーワードがIS-A関係を得るためにどのように使用されるか見てみましょう。
一般的にimplementsキーワードは、インターフェースのプロパティを継承するためにクラスで使用されます。インターフェースはクラスによって拡張されることはありません。
例
public interface Animal {
}
public class Mammal implements Animal {
}
public class Dog extends Mammal {
}
instanceofキーワード
instanceof演算子を使用して、Mammalが実際にAnimalか、Dogが実際にAnimalかを判定します。
例
interface Animal {}
class Mammal implements Animal {}
public class Dog extends Mammal {
public static void main(String args[]) {
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal);
System.out.println(d instanceof Mammal);
System.out.println(d instanceof Animal);
}
}
出力
true
true
true
HAS-A関係
これらの関係は主に使用法に基づいています。あるクラスがHAS-A(〜を持つ)特定のものを持つかどうかを決定します。この関係はコードの重複とバグを減らすのに役立ちます。
例を見てみましょう。
例
public class Vehicle {}
public class Speed {}
public class Van extends Vehicle {
private Speed sp;
}
これはVanクラスがSpeedをHAS-A(持つ)ことを示しています。Speed用の別クラスを持つことで、Speedに属するコード全体をVanクラス内に入れる必要がなくなり、Speedクラスを複数のアプリケーションで再利用可能になります。
オブジェクト指向機能では、ユーザーはどのオブジェクトが実際の作業を行っているかを気にする必要がありません。これを達成するために、Vanクラスは実装の詳細をVanクラスのユーザーから隠蔽します。基本的に起こることは、ユーザーがVanクラスに特定のアクションを依頼し、Vanクラスが自分で作業するか、別のクラスにアクションを実行させるかのどちらかです。
継承の種類
以下に示すように、継承にはさまざまな種類があります。

覚えておくべき非常に重要な事実は、Javaは多重継承をサポートしていないことです。これはクラスが1つ以上のクラスを拡張できないことを意味します。したがって以下は違法です。
違法な例
public class extends Animal, Mammal {}
しかし、クラスは1つ以上のインターフェースを実装できるため、これがJavaで多重継承の不可能性を克服するのに役立っています。
Java
- C# 継承をマスターする:概念、種類、実践コード
- C#の継承:再利用可能で保守しやすいコードを構築する
- Javaのfinalキーワード完全解説:変数、メソッド、クラスでの活用法
- Java instanceof演算子完全ガイド:基本から継承・インターフェースまで
- Java Staticネストクラスの理解:用法、違い、実例
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaシングルトンパターン完全解説:安全な実装と活用法
- Javaリフレクション完全ガイド:実行時のクラス・メソッド・フィールド検査
- Java ObjectOutputStream完全ガイド:シリアル化、メソッド、実践例
- Javaジェネリクス完全ガイド:再利用可能で型安全なコードの構築
- Javaファイル操作のマスター:java.ioによる作成・読み取り・書き込み・削除