【Java】レッスン5-07:抽象クラスの仕組みと使い方をわかりやすく解説

一つ前のページではメソッドのオーバーライドについて学習しました。
今回は 抽象クラス について見ていきましょう。
Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編
Lesson4:コレクション編
Lesson5:クラス編
・Lesson5-1:クラスの基本を確認しよう
・Lesson5-2:コンストラクタを理解しよう
・Lesson5-3:カプセル化を理解しよう
・Lesson5-4:クラスメンバとインスタンスメンバを理解しよう
・Lesson5-5:クラスの継承を理解しよう
・Lesson5-6:メソッドのオーバーライドを理解しよう
・Lesson5-7:抽象クラスを理解しよう ◁今回はココ
・Lesson5-8:インターフェースを理解しよう
・確認問題5-☆1:モンスター捕獲ゲームを作ろう
・確認問題5-☆2:モンスターとのバトルゲームを作ろう
・確認問題5-☆3:マルバツゲーム(Tic-Tac-Toe)を作成しよう
Javaの抽象クラスとは?仕組みと基本の使い方を学ぼう

Javaのプログラミングにおいて、「抽象クラス」はオブジェクト指向の概念の一つです。
複数のクラスで共通の機能を持たせたいときに、抽象クラスを利用することでコードの再利用性を高めることができます。
本節では抽象クラスの定義方法とその基本的な使い方について学びましょう。

抽象クラスの定義と特徴とは?
抽象クラスは「インスタンス生成できないクラス」であり、他の子クラスに継承されることを前提としています。
通常のクラスと同様に変数やメソッドを持つことができますが、特定のメソッドにおいて実装を持たない「抽象メソッド」を含めることができる点が特徴です。
抽象クラスを使うことで共通の基盤を提供し、複数の子クラスでの個別の実装を促すことができます。
抽象クラスと抽象メソッドの書き方
抽象クラスと抽象メソッドの定義は、以下のように行います。
抽象クラスは abstract
キーワードを用いて宣言し、抽象メソッドも同様に abstract
キーワードを使って定義します。
// 抽象クラスの例 abstract class Animal { // 抽象メソッド(具体的な実装を持たない) abstract void sound(); // 通常のメソッド(実装を持つ) void sleep() { System.out.println("Sleeping..."); } }
上記の例ではAnimal
クラスは抽象クラスであり、sound()
メソッドが抽象メソッドとして定義されています。
sound()
メソッドはAnimal
クラスを継承した子クラスで実装されることを期待しています。
Dog・Catクラスを使った抽象クラスの活用例
抽象クラスを使うと共通の動作を持ちながらも、具体的な部分を子クラスで自由に定義できます。
次にDog
と Cat
という2つのクラスが Animal
クラスを継承し、各クラスで異なる sound()
メソッドを実装する例を見てみましょう。
// 抽象クラスの例 abstract class Animal { // 抽象メソッド(具体的な実装を持たない) abstract void sound(); // 通常のメソッド(実装を持つ) void sleep() { System.out.println("Sleeping..."); } }
この例ではDog
クラスと Cat
クラスが Animal
クラスを継承し、それぞれのクラスで sound()
メソッドを独自に実装しています。
Main
クラスの main
メソッド内で myDog
と myCat
をそれぞれインスタンス化して sound()
を呼び出すと、各クラスの実装に従った出力が得られます。
またsleep()
メソッドは Animal
クラスで既に実装されているため、子クラスで再定義する必要がありません。
抽象クラスを使う利点|共通動作と柔軟な設計
抽象クラスを使う主なメリットは、共通の基盤を提供しつつ子クラスに実装を委ねることができる点です。
これにより各クラスの実装をカスタマイズしやすくなり、コードの可読性とメンテナンス性が向上します。
また抽象クラスを利用することで、設計時に共通のインターフェースや動作を規定でき、後から拡張しやすい柔軟なコードを書くことができます。
学んだ内容のふり返りと次のステップ
抽象クラスはJavaでのオブジェクト指向設計において重要な役割を担う概念です。
共通の動作や構造を定義しつつ、具体的な実装は子クラスで行うため、継承関係を活かした柔軟なプログラムが実現できます。
これで抽象クラスの基本が理解できたでしょうか?
次の練習問題で実際にコードを書きながらさらに理解を深めていきましょう!
練習問題|抽象クラスの活用で鳴き声を出力するプログラムを作成しよう

動物の種類によって異なる鳴き声を表示するプログラムを作成しましょう。
このプログラムでは動物の基本的なクラスとして抽象クラスを使い、それぞれの動物(犬と猫)に特有の鳴き声を実装します。
また共通の動作としてすべての動物が「寝ている」という動作も表示させましょう。
この問題の要件
以下の要件に従ってコードを完成させてください。
- 抽象クラス
Animal
を定義し、以下の内容を持たせること。makeSound()
という抽象メソッドを宣言すること(戻り値はvoid
)。sleep()
という具象メソッドを実装し、「動物は寝ています…」と表示すること。
Animal
クラスを継承するDog
クラスを定義し、以下を実装すること。makeSound()
メソッドで「ワンワン!」と出力すること。
Animal
クラスを継承するCat
クラスを定義し、以下を実装すること。makeSound()
メソッドで「ニャーニャー!」と出力すること。
Main
クラスのmain
メソッドで、以下を実行すること。Dog
クラスのインスタンスを生成し、そのmakeSound()
メソッドとsleep()
メソッドを呼び出すこと。Cat
クラスのインスタンスを生成し、そのmakeSound()
メソッドとsleep()
メソッドを呼び出すこと。
ただし、以下のような実行結果となること。
ワンワン! ニャーニャー! 動物は寝ています... 動物は寝ています...
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)1:抽象クラスAnimalの定義
□ 抽象メソッドmakeSoundの宣言
□ 具象メソッドsleepの定義
□ 「動物は寝ています…」と出力2:Dogクラスの定義
□ Animalクラスを継承
□ makeSoundメソッドをオーバーライドし、「ワンワン!」と出力3:Catクラスの定義
□ Animalクラスを継承
□ makeSoundメソッドをオーバーライドし、「ニャーニャー!」と出力4:Mainクラスの定義
□ mainメソッドの定義
□ □ Dogクラスのインスタンスを生成し、変数dogに代入
□ □ Catクラスのインスタンスを生成し、変数catに代入
□ □ dogのmakeSoundメソッドを呼び出し、鳴き声を出力
□ □ catのmakeSoundメソッドを呼び出し、鳴き声を出力
□ □ dogのsleepメソッドを呼び出し、「動物は寝ています…」を出力
□ □ catのsleepメソッドを呼び出し、「動物は寝ています…」を出力
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// 動物の種類を表す抽象クラス abstract class Animal { /*【穴埋め問題1】 ここに抽象メソッドmakeSoundを宣言してください。 */ // 共通の動作を定義するメソッド public void sleep() { System.out.println("動物は寝ています..."); } } // 犬のクラス (Animalクラスを継承して実装) class Dog extends Animal { /*【穴埋め問題2】 ここにmakeSoundメソッドをオーバーライドし、「ワンワン!」と出力するコードを書いてください。 */ } // 猫のクラス (Animalクラスを継承して実装) class Cat extends Animal { /*【穴埋め問題3】 ここにmakeSoundメソッドをオーバーライドし、「ニャーニャー!」と出力するコードを書いてください。 */ } public class Main { public static void main(String[] args) { // DogとCatのインスタンスを作成し、動作を確認する Animal dog = new Dog(); // DogはAnimalのサブクラス Animal cat = new Cat(); // CatはAnimalのサブクラス // 各動物の鳴き声を出す (抽象メソッドの実装部分が呼び出される) dog.makeSound(); cat.makeSound(); // sleepメソッドはAnimalクラスで実装されているので、直接使用できる dog.sleep(); cat.sleep(); } }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
練習問題の解答と解説
この問題の正解コードとその解説は以下の通りです。
クリックして開いて確認してください。
- 正解コード
-
// 動物の種類を表す抽象クラス abstract class Animal { // 抽象メソッド: 具体的な動物クラスで実装する必要がある public abstract void makeSound(); // 共通の動作を定義するメソッド public void sleep() { System.out.println("動物は寝ています..."); } } // 犬のクラス (Animalクラスを継承して実装) class Dog extends Animal { // 抽象メソッドを具体的に実装する @Override public void makeSound() { System.out.println("ワンワン!"); } } // 猫のクラス (Animalクラスを継承して実装) class Cat extends Animal { // 抽象メソッドを具体的に実装する @Override public void makeSound() { System.out.println("ニャーニャー!"); } } public class Main { public static void main(String[] args) { // DogとCatのインスタンスを作成し、動作を確認する Animal dog = new Dog(); // DogはAnimalのサブクラス Animal cat = new Cat(); // CatはAnimalのサブクラス // 各動物の鳴き声を出す (抽象メソッドの実装部分が呼び出される) dog.makeSound(); cat.makeSound(); // sleepメソッドはAnimalクラスで実装されているので、直接使用できる dog.sleep(); cat.sleep(); } }
- 正解コードの解説
-
コードをブロックごとに分割して解説します。
抽象クラスと抽象メソッド
abstract class Animal { public abstract void makeSound(); public void sleep() { System.out.println("動物は寝ています..."); } }
- 抽象クラス(
abstract class Animal
)
抽象クラスAnimal
は「動物」を表す基本クラスであり、特定の動作を子クラスで実装するための基盤です。abstract
キーワードによりこのクラスは直接インスタンス化できず、他のクラスが継承するためだけに存在します。 - 抽象メソッド(
public abstract void makeSound();
)makeSound
は抽象メソッドです。抽象メソッドは具体的な処理を持たず、子クラスで必ず実装されなければなりません。このメソッドを通して動物ごとに異なる鳴き声を定義できます。 - 具象メソッド(
public void sleep()
)sleep
メソッドは具体的な処理を持つメソッドで、すべての動物が同じ動作(「寝ています…」のメッセージ出力)を行います。抽象クラス内に具象メソッドを定義することで共通の動作を各子クラスに引き継げます。
犬のクラスの定義
class Dog extends Animal { @Override public void makeSound() { System.out.println("ワンワン!"); } }
- 継承(
class Dog extends Animal
)Dog
クラスはAnimal
クラスを継承しているため、Animal
クラスのすべてのメソッドやプロパティを利用できます。ここではmakeSound
メソッドを具体的に実装する必要があるため@Override
アノテーションを使用します。 - メソッドのオーバーライド
makeSound
メソッドをオーバーライドして犬の鳴き声「ワンワン!」を出力するようにしています。これにより、犬特有の動作を表現できます。
猫のクラスの定義
class Cat extends Animal { @Override public void makeSound() { System.out.println("ニャーニャー!"); } }
- 継承とメソッドのオーバーライド
Cat
クラスもAnimal
クラスを継承しており、makeSound
メソッドをオーバーライドして猫の鳴き声「ニャーニャー!」を出力します。これにより、異なる動物がそれぞれの鳴き声を持つことができます。
Mainクラスとメインメソッド
- インスタンス化とポリモーフィズム
Animal
型の変数dog
にDog
クラスのインスタンスを、cat
にCat
クラスのインスタンスを代入しています。Animal
型を通して異なるクラスのオブジェクトを扱うことで、ポリモーフィズムを活用しています。これにより、makeSound
メソッドはdog
では「ワンワン!」、cat
では「ニャーニャー!」と異なる動作を行います。 - メソッドの呼び出し
makeSound
メソッドを呼び出すと、それぞれの鳴き声が出力されます。また、sleep
メソッドはAnimal
クラスで定義されているため、すべてのAnimal
クラスを継承したインスタンスが同じ「動物は寝ています…」のメッセージを表示します。
- 抽象クラス(
まとめ
このコードを通じてJavaの「抽象クラス」や「抽象メソッド」の概念を学びました。
抽象クラスは特定の機能を実装しないまま共通の構造を提供し、子クラスに具体的な動作を割り当てるために使われます。
抽象クラスを使うと異なる動物がそれぞれの特性を持つ柔軟なプログラムを実現できます。