Javaのabstractキーワードの使い方を徹底解説!抽象クラスを簡単に作る方法
生徒
「Javaのabstractってどう使うんですか?なんだか難しそうで…」
先生
「abstractは、抽象クラスや抽象メソッドを作るときに使うキーワードです。オブジェクト指向プログラミングでとても大切ですよ。」
生徒
「抽象クラスって普通のクラスと何が違うんですか?」
先生
「具体的な処理を持たずに、設計図のような役割を持つクラスですね。実際にJavaでabstractを使って、どうやって抽象クラスを定義するのか見ていきましょう!」
1. abstractキーワードとは?Javaの基本構文を理解しよう
Javaにおけるabstractキーワードは、クラスやメソッドが“未完成”であることを示します。つまり、「このクラス(またはメソッド)は継承されて使われることが前提ですよ」という意味を持ちます。
主に次の2つで使われます。
- 抽象クラスの定義(
abstract class) - 抽象メソッドの定義(
abstract メソッド名();)
抽象クラスは、直接インスタンス化(new)できません。サブクラスで継承して、具体的な処理を実装することで初めて使えるようになります。
2. abstractを使った抽象クラスの基本例
ここでは、Javaでabstractを使って簡単な抽象クラスを作る方法を紹介します。
public abstract class Animal {
public void eat() {
System.out.println("エサを食べる");
}
// 抽象メソッド(中身がない)
public abstract void makeSound();
}
eat()メソッドのように、実装されたメソッドも定義できますが、makeSound()のように中身のないメソッドは、継承先で必ず実装しなければなりません。
3. 抽象クラスを継承して具体的なクラスを作る
抽象クラスを使うには、サブクラスを作って中身を補う必要があります。以下はAnimalクラスを継承するDogクラスの例です。
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("ワンワン!");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.eat();
dog.makeSound();
}
}
エサを食べる
ワンワン!
このように、抽象クラスに定義された抽象メソッドは、継承先のクラスで必ずオーバーライドして実装しなければエラーになります。
4. abstractメソッドの注意点と制限
abstractメソッドには中括弧{}で囲った処理内容を書けません。あくまで宣言のみです。また、抽象メソッドを定義するには、必ずクラス自体もabstractである必要があります。
以下のようなコードはコンパイルエラーになります。
// エラーになる例
public class Test {
public abstract void run() {
System.out.println("走る");
}
}
抽象メソッドには処理を書かず、サブクラスに任せるのがルールです。
5. abstractを使うべき場面と設計の考え方
abstractを使って抽象クラスを作るべきタイミングは、「複数のクラスに共通する振る舞いがあり、かつ一部の処理はそれぞれ異なる」場合です。
たとえば「動物」や「乗り物」など、共通の概念を持つが挙動が異なるグループを扱う際に抽象クラスは非常に役立ちます。
- 共通の処理 → 抽象クラスに実装
- 個別の処理 → 抽象メソッドにして継承先で実装
このような構造にすることで、保守性が高く、再利用性のあるクラス設計が実現できます。
6. abstractとinterfaceの違いにも注目しよう
Javaではabstractを使う抽象クラスとinterface(インターフェース)の両方が似たような目的で使われますが、明確な違いがあります。
- 抽象クラスは共通の処理(ロジック)を含められる
- インターフェースは処理を含まず、複数実装可能
インターフェースは“契約”、抽象クラスは“雛形”という違いがあり、使い分けが大切です。
まとめ
abstractキーワードを理解すると設計力が大きく伸びる
ここまで、Javaのabstractキーワードと抽象クラスの使い方について詳しく解説してきました。abstractは、Javaのオブジェクト指向プログラミングを理解するうえで欠かせない重要なキーワードです。抽象クラスは「完成していないクラス」であり、そのままでは使えない代わりに、設計の共通部分をまとめる役割を担います。複数のクラスに共通する考え方や処理を抽象クラスとして定義することで、コードの重複を減らし、読みやすく整理されたプログラムを作ることができます。
Javaの学習を始めたばかりの頃は、すべてのクラスを普通のクラスとして書いてしまいがちですが、プログラムの規模が大きくなるほど、abstractを使った設計の重要性が見えてきます。抽象クラスを使うことで、「このクラスは必ずこのメソッドを実装しなければならない」というルールを明確にでき、チーム開発や長期的な保守にも強いコードになります。
抽象クラスと抽象メソッドの役割を整理しよう
abstractキーワードには、抽象クラスと抽象メソッドという二つの使い方がありました。抽象クラスは共通処理を持つことができ、抽象メソッドは処理内容を持たず、継承先のクラスに実装を強制します。この仕組みにより、サブクラスごとの違いを明確にしながら、共通の構造を保つことが可能になります。
特に、abstractメソッドは「必ずオーバーライドされるべき処理」を表現するために使われます。これにより、実装漏れをコンパイル時に防げる点もJavaの大きなメリットです。抽象クラスを正しく使いこなすことで、設計段階でのミスを減らし、安心して機能追加や修正ができるようになります。
まとめとしてのサンプルプログラム
最後に、abstractキーワードの考え方を振り返るためのシンプルなサンプルプログラムを確認してみましょう。共通の振る舞いと、クラスごとに異なる処理をどのように分けているかがポイントです。
public abstract class Vehicle {
public void start() {
System.out.println("乗り物が発進します");
}
public abstract void run();
}
public class Car extends Vehicle {
@Override
public void run() {
System.out.println("車が道路を走ります");
}
}
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new Car();
vehicle.start();
vehicle.run();
}
}
乗り物が発進します
車が道路を走ります
この例では、Vehicleという抽象クラスに共通処理であるstartメソッドを定義し、runメソッドを抽象メソッドとして宣言しています。CarクラスはVehicleを継承し、runメソッドを具体的に実装しています。このような構成にすることで、将来バイクや電車などのクラスを追加する場合でも、同じ設計ルールのもとで拡張できます。
abstractを使ったクラス設計は、最初は難しく感じるかもしれませんが、慣れてくると「どこを共通化すべきか」「どこをサブクラスに任せるべきか」を考える力が自然と身についてきます。Javaの基礎から一歩進んだ理解として、ぜひ意識して使ってみてください。
生徒
「abstractクラスって、ただ難しい仕組みだと思っていましたが、共通の設計をまとめるためのものなんですね。」
先生
「その理解はとても大切です。抽象クラスは、プログラム全体の形を整えるための道具なんですよ。」
生徒
「抽象メソッドがあることで、サブクラスで実装し忘れる心配が減るのも安心だと思いました。」
先生
「そうですね。Javaはコンパイル時にチェックしてくれるので、設計ミスに早く気づけます。」
生徒
「これからは、共通の処理があるときにabstractクラスを使えるか考えてみます。」
先生
「それができれば、Javaのオブジェクト指向設計はかなり理解できていますよ。」