前回は、オブジェクト指向の重要な考え方の一つであるカプセル化について学習しました。
privateを使ってデータを保護し、getterやsetterを利用してデータを管理する方法を紹介しました。
今回は、オブジェクト指向のもう一つの重要な仕組みである継承について学んでいきます。
継承とは、あるクラスのフィールドやメソッドを、別のクラスが引き継いで利用する仕組みです。
例えば、「車」と「スポーツカー」を考えてみましょう。
車には「走る」という共通の機能があります。
スポーツカーも車なので、「走る」という機能を持っています。
このような共通する機能を親クラスにまとめ、子クラスで利用することができます。
継承では、元になるクラスを親クラス、そのクラスを継承するクラスを子クラスと呼びます。
親クラス
Car
↓
子クラス
SportsCar
SportsCarはCarの機能を引き継ぐことができます。
public class Car {
public void run() {
System.out.println("車が走ります。");
}
}
Carクラスには、車が走る処理を用意しました。
Carクラスを継承して、SportsCarクラスを作ってみましょう。
public class SportsCar extends Car {
}
extendsを使うことで、Carクラスを継承できます。
public class Main {
public static void main(String[] args) {
SportsCar car = new SportsCar();
car.run();
}
}
車が走ります。
SportsCarクラスにはrun()メソッドを書いていません。
それでも実行できるのは、Carクラスからrun()メソッドを継承しているためです。
子クラスには、親クラスから引き継いだ機能だけでなく、独自の機能を追加することもできます。
public class SportsCar extends Car {
public void turbo() {
System.out.println("ターボで加速します。");
}
}
SportsCarには、独自のturbo()メソッドを追加しました。
public class Main {
public static void main(String[] args) {
SportsCar car = new SportsCar();
car.run();
car.turbo();
}
}
車が走ります。
ターボで加速します。
このように、子クラスでは親クラスの機能+子クラス独自の機能を利用できます。
継承したメソッドを、子クラス側で自分の処理に書き換えることもできます。
これをオーバーライドと呼びます。
public class SportsCar extends Car {
@Override
public void run() {
System.out.println("スポーツカーが高速で走ります。");
}
}
Carクラスのrun()メソッドを、SportsCar用の処理に変更しています。
public class Main {
public static void main(String[] args) {
SportsCar car = new SportsCar();
car.run();
}
}
スポーツカーが高速で走ります。
オーバーライドするときには、メソッドの前に@Overrideと記述するのが一般的です。
@Override
public void run() {
System.out.println("スポーツカーが高速で走ります。");
}
@Overrideは、「親クラスのメソッドを上書きしています」とJavaに伝えるためのものです。
記述しておくことで、メソッド名の書き間違いなどにも気付きやすくなります。
継承を利用すると、共通する処理を何度も書く必要がなくなります。
例えば、次のようなクラスがあるとします。
Car
SportsCar
Truck
それぞれのクラスに「走る」という処理を書くのではなく、共通する処理をCarクラスにまとめることができます。
Car
│
┌─────┴─────┐
↓ ↓
SportsCar Truck
このように、共通する機能をまとめることで、プログラムを整理しやすくなります。
public class SportsCar {
}
これではCarクラスを継承していません。
Carを継承する場合は、次のように記述します。
public class SportsCar extends Car {
}
@Override
public void runCar() {
System.out.println("走ります。");
}
親クラスのメソッド名と一致していないため、正しくオーバーライドできません。
@Overrideを付けておくと、このような間違いを発見しやすくなります。
継承は便利な仕組みですが、何でも継承すればよいというわけではありません。
「親子関係として自然か?」を考えることが重要です。
例えば、
Car
↓
SportsCar
は「スポーツカーは車である」という関係なので自然です。
このような関係を意識してクラスを設計しましょう。
次回は、ポリモーフィズムについて解説します。