手を動かして学ぶ Java入門 (抽象クラスと抽象メソッド)
環境構築不要! ブラウザから直接コードを実行できます。
本記事では、抽象クラスと抽象メソッドについて学びます。
10分くらいで、さくっと終わる記事をめざしています。
シリーズ一覧
- シリーズ
- 手を動かして学ぶ Java入門 (Hello world 編)
- 手を動かして学ぶ Java入門 (数値と演算)
- 手を動かして学ぶ Java入門 (数値と変数)
- 手を動かして学ぶ Java入門 (コメントの書き方)
- 手を動かして学ぶ Java入門 (文と式の違い)
- 手を動かして学ぶ Java入門 (if文)
- 手を動かして学ぶ Java入門 (if-else文、if-elseif文)
- 手を動かして学ぶ Java入門 (文字列の連結)
- 手を動かして学ぶ Java入門 (while文)
- 手を動かして学ぶ Java入門 (break文)
- 手を動かして学ぶ Java入門 (continue文)
- 手を動かして学ぶ Java入門 (for文)
- 手を動かして学ぶ Java入門 (クラスの超基本)
- 手を動かして学ぶ Java入門 (クラス・メソッド)
- 手を動かして学ぶ Java入門 (クラス・フィールド)
- 手を動かして学ぶ Java入門 (クラス・コンストラクタ)
- 手を動かして学ぶ Java入門 (文字列クラス)
- 手を動かして学ぶ Java入門 (静的メソッド)
- 手を動かして学ぶ Java入門 (静的フィールド)
- 手を動かして学ぶ Java入門 (定数の定義)
- 手を動かして学ぶ Java入門 (クラス継承の超基本)
- 手を動かして学ぶ Java入門 (メソッドのオーバーライド)
- 手を動かして学ぶ Java入門 (メソッドのオーバーロード)
- 手を動かして学ぶ Java入門 (thisキーワード)
- 手を動かして学ぶ Java入門 (superキーワード)
- 手を動かして学ぶ Java入門 (抽象クラスと抽象メソッド)
続きは近日公開予定!
はじめに
この記事は paiza.IO の「Online Java compiler」を利用しています。
2025/1/16 現在、上記環境の Java バージョンは 18 です。(paiza.IO利用ガイド)
実行したコードは paiza.IO で保存および公開されることがあります。
そのため、個人情報などの機密性の高い情報は、コードとして入力しないようにご注意ください。
詳細は paiza.IO の利用規約およびプライバシーポリシーをご確認ください。
概要
抽象クラスとは
抽象クラスとは、簡単にいうと…
- 1つ以上の 抽象メソッド を宣言したクラス
のことです。
今まで学習してきた通常のクラスは 抽象メソッド を1つも持たないクラスです。
そして、今回学ぶ抽象クラスは、抽象メソッド を持ちます。
違いはそれだけです。
こんなイメージですね。
(抽象メソッドについては後ほど解説します)
抽象クラスを宣言するには abstract キーワードを使います。
abstract は「抽象的な」という意味ですね。
public abstract class AbstractSample {
^^^^^^^^ <--- ★この部分!
...
}
ノート
- 厳密には、抽象メソッドが0個の抽象クラスも宣言できます。
ただ、そんなクラスを抽象クラスにする意味はあるのか?といわれると微妙で、使われているのはあまり見ないですね…
抽象メソッドとは
抽象メソッドとは、簡単にいうと…
- 実装のないメソッド
のことです。
「実装」とは、具体的に 記述されたコードになります。
抽象メソッドを宣言するには、abstract キーワードを使います。
抽象クラスと同じキーワードですね。
public abstract class AbstractSample {
public abstract void print();
^^^^^^^^ <--- ★この部分!
}
上記の print メソッドは抽象メソッドです。
通常のメソッドなら…
public void print() {
System.out.println("テスト!");
}
こんな感じで { ... } のところに実際のコードを書いていました。
しかし、抽象メソッドでは { ... } がなくて、いきなりセミコロン(;) で終わらせます。
public abstract void print();
^ <--- コードの実装がない
これが抽象メソッドです。
抽象メソッドのオーバーライド
さて、抽象メソッドは実装がありません。
そんな抽象メソッドを持つ抽象クラスを new したらどうなるのでしょうか?
public abstract class AbstractSample {
public abstract void print();
}
AbstractSample sample = new AbstractSample();
sample.print();
それでは、実際にプログラムを動かして確認してみましょう。
コードは変更せずに、そのまま「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか? 下記のようなコンパイルエラーが出たら成功です。
Main.java:4: error: AbstractSample is abstract; cannot be instantiated
AbstractSample sample = new AbstractSample();
^
1 error
"AbstractSample is abstract; cannot be instantiated" とは、意訳すると
- AbstractSample は抽象クラスです。よってインスタンス化できません。
という感じです。
確かに、仮にインスタンスの生成ができたとしても…
AbstractSample sample = new AbstractSample();
sample.print();
^^^^^^^ <--- ★なにを実行するべきか分からない
実装のない print メソッドを呼び出して結局エラーになりそうですしね。
さて、そんな抽象メソッドですが、いったいどうやって使うのでしょうか?
その答えはメソッドの オーバーライド にあります。
メソッドのオーバーライドについては 以前の記事 でも解説しました。
よろしければそちらもぜひご参照ください。
ちなみに、メソッドの オーバーロード とは違うのでご注意を…
それでは、さっそく抽象メソッドの print メソッドをオーバーライドしてみましょう。
オーバーライドするには、クラスを継承するのでしたね。
public class Sample extends AbstractSample {
@Override
public void print() {
System.out.println("オーバーライド!");
}
}
AbstractSample クラスを継承した Sample クラスを作ってみました。
実際にプログラムを動かして確認してみましょう。
結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは3ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか? 「出力」のところに
オーバーライド!
と表示されたら成功です。
無事に抽象メソッドをオーバーライドできました。
メリット
抽象クラスは、そのままではインスタンス化できません。
つまり、サブクラスを作ることを強制し、さらに抽象メソッドをオーバーライドすることも強制します。
これが抽象クラス・抽象メソッドのメリットになります。
…といっても、最初のうちはピンとこないかもしれません。
Java のことが分かってきて、オブジェクト指向もなんとなく理解して…
デザインパターン なんかを使い始めるとメリットが理解できてくるかと思います。
それまでは、そんなに積極的に使わなくてもよいのかな、と個人的には思います。
頭の片隅にでも置いておきましょう。
応用問題
【問題】
まずは、下記のプログラムをそのまま「実行(Ctrl-Enter)」してみましょう。
結果はコンパイルエラーになったはずです。
Sample.java:1: error: Sample is not abstract and does not override abstract method getValue() in AbstractSample
public class Sample extends AbstractSample {
^
1 error
これは Sample クラスで、抽象メソッドの getValue メソッドをオーバーライドしていないためです。
そこで問題です。
Sample クラスで getValue メソッドをオーバーライドして、プログラムを実行すると、
value = 123
と「出力」に表示されようにしてください。
それでは、Sample クラスに getValue メソッドをオーバーライドしてから「実行(Ctrl-Enter)」してみましょう。
(修正するのは Sample クラスだけです)
注意:コードは3ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
無事に、
value = 123
と出力されましたでしょうか?
もし解けなかった場合は、下記の回答例をご参照ください。
回答例
【コード】
public class Sample extends AbstractSample {
// 抽象メソッドをオーバーライドしてください
@Override
public int getValue() {
return 123;
}
}
※ Main.java, AbstractSample.java は書き換えません。
【出力】
value = 123
まとめ
抽象クラスとは簡単にいうと…
- 1つ以上の 抽象メソッド を宣言したクラス
のことです。
そして、抽象メソッドとは簡単にいうと…
- 実装のないメソッド
のことです。
抽象クラスは、そのままではインスタンス化できません。
つまり、サブクラスを作ることを強制し、さらに抽象メソッドをオーバーライドすることも強制します。
それでは次回もお楽しみに!
関連記事
- シリーズ
- 手を動かして学ぶ Java入門 (Hello world 編)
- 手を動かして学ぶ Java入門 (数値と演算)
- 手を動かして学ぶ Java入門 (数値と変数)
- 手を動かして学ぶ Java入門 (コメントの書き方)
- 手を動かして学ぶ Java入門 (文と式の違い)
- 手を動かして学ぶ Java入門 (if文)
- 手を動かして学ぶ Java入門 (if-else文、if-elseif文)
- 手を動かして学ぶ Java入門 (文字列の連結)
- 手を動かして学ぶ Java入門 (while文)
- 手を動かして学ぶ Java入門 (break文)
- 手を動かして学ぶ Java入門 (continue文)
- 手を動かして学ぶ Java入門 (for文)
- 手を動かして学ぶ Java入門 (クラスの超基本)
- 手を動かして学ぶ Java入門 (クラス・メソッド)
- 手を動かして学ぶ Java入門 (クラス・フィールド)
- 手を動かして学ぶ Java入門 (クラス・コンストラクタ)
- 手を動かして学ぶ Java入門 (文字列クラス)
- 手を動かして学ぶ Java入門 (静的メソッド)
- 手を動かして学ぶ Java入門 (静的フィールド)
- 手を動かして学ぶ Java入門 (定数の定義)
- 手を動かして学ぶ Java入門 (クラス継承の超基本)
- 手を動かして学ぶ Java入門 (メソッドのオーバーライド)
- 手を動かして学ぶ Java入門 (メソッドのオーバーロード)
- 手を動かして学ぶ Java入門 (thisキーワード)
- 手を動かして学ぶ Java入門 (superキーワード)
- 手を動かして学ぶ Java入門 (抽象クラスと抽象メソッド)