検索

キーワード


【Java】抽象クラスとは?その特徴やインターフェースとの違いを解説

  • 公開日:2020-09-07 15:18:08
  • 最終更新日:2021-01-25 19:33:46
【Java】抽象クラスとは?その特徴やインターフェースとの違いを解説

こんにちは、駆け出しプログラマーの若江です!

ここでは初学者として学習を終えた私からアウトプットの意味も込めて、

抽象クラスについて紹介させていただきます。

できる限り初学者が理解しやすい内容として紹介させていただくので、参考となれば幸いです!


関連記事リンク:インターフェースの紹介 / 継承とオーバーライドの紹介 / コンストラクタの紹介 / メソッドの紹介 / インスタンスの紹介 / アクセス修飾子の紹介

抽象クラス/抽象メソッド

継承と深く関わりのある機能の一つが抽象クラスです。

ここでは抽象クラスの概念、メリット、使い方や、

同じような特徴を持つインターフェースとの違いについて紹介させていただきます。


抽象クラスとは?

abstract 修飾子の付いたクラスを抽象クラスと呼びます。

抽象メソッドを持っていなくても上記条件に当てはまれば抽象クラスと呼びますが、

通常は抽象メソッドを1つ以上持つクラスに abstract 修飾子を付けます。

抽象メソッド: 基本構文/ abstract 戻り値の型 メソッド名(引数の型 引数);

 abstract 修飾子、戻り値の型、メソッド名、引数の型、引数を持つメソッドです。

 通常のメソッド(具象メソッド)のように動作処理( {} 内の処理)を持っておらず、

 代わりに abstract 修飾子を持つ特徴があります。

 またアクセス修飾子はデフォルト、protected、public を付けることができます。

 アクセス修飾子の特性上外部パッケージでクラスの継承をする際は、

 protected もしくは public にしなければならないことに気を付けましょう。

また抽象メソッドを持つクラスは、抽象クラス(クラスの定義にabstractを付与)にする必要があります。


◆抽象クラスと抽象メソッドの例(引数なし)

public abstract class AbstractTest {

	abstract String callName();
}


抽象クラスは継承することを前提に作られたクラスで、

抽象クラスそのものをインスタンス化することができません。



抽象クラスのメリット

通常のクラスを作らずに抽象クラスを作るメリットは以下のようなものが挙げられます。

 ※ここではクラスを区別するために通常のクラスを「具象クラス」と呼びます。


・共通処理をまとめられる:

複数の具象クラスが共通して同じような動作をするメソッドを持っていた場合に、

それらメソッドを1つの抽象クラスにまとめることができます。

まとめられる共通処理は「全く同じ処理」以外にも「詳細は異なるが大きな括りでは同じ処理」も含みます。


スマホを例にしてみましょう。

「充電をする」や「タッチパネルで操作する」といった処理は、あなたのスマホも周りの人のスマホも全く同じ処理をします。

一方「着信を知らせる」や「時刻表示をする」といった処理自体は共通していますが、

着信方法が「マナーモード」「音通知」や、時刻表示に「東京時刻」「アメリカ時刻」があるように

あなたのスマホと周りの人のスマホで詳細は異なるが大きな括りでは同じ処理をする

といったようなイメージです。


抽象クラスが持つ「全く同じ処理」が具象メソッド、

「詳細は異なるが大きな括りでは同じ処理」が抽象メソッドにあたります。

抽象メソッドは、上記のように具体的な処理内容を継承先クラスに任せることができます。


・共通処理をするメソッド名に統一性を持たせられる:

上記メリットのように、抽象クラスに同じような処理をするメソッドの定義をまとめることができるため、

それを継承した具象クラスでメソッド名に統一性を持たせることができます。

また抽象クラスを継承した具象クラスは、抽象メソッドの処理を必ず記述しなければなりません。

そのため抽象クラスを継承した具象クラスには強制的に同じメソッド名のメソッドを持たせることができます。


チーム開発の場面を想像してみると良いかもしれません。

チームでそれぞれ1つずつ「挨拶」メソッドを持ったクラスを作るとします。

もし抽象クラス機能が無かった場合、Aさんが作ったクラスAは「hello」メソッドを持っていて、

Bさんが作ったクラスBは「hi」メソッド、CさんのクラスCは「goodMorning」、DさんのクラスDは「byebye」メソッド

となってしまう可能性があり、無駄な労力がかかることが予想できます。




抽象クラスの使い方

抽象クラスのメリットを踏まえながら、具体的な抽象クラスの使い方も見ていきましょう。

先ほど例に出したスマホの機能を例に抽象クラスを作り、

具象クラスへ継承して2つのスマホクラスを作る簡単なサンプルコードを作成します。


抽象クラスの継承方法

・抽象クラスの抽象メソッドは具象クラスでオーバーライドします。

・抽象クラスから具象クラスへは通常の継承と同じく extends で行います。

・継承の特性上抽象クラスが持つ具象メソッドは、具象クラスで記述不要です。


◆抽象クラスの作成と継承例

【抽象クラス】 抽象メソッド2つと具象メソッド2つを持つ抽象クラス

public abstract class AbstractTest {

	// 着信通知方法の抽象メソッド
	abstract String incoming();

	// 時刻表時の抽象メソッド
	abstract String time(int hour, int minuites);

	// 呼ばれると充電値を 1 増やす具象メソッド
	public int charge(int num) {
		return num += 1;
	}

	// 触れた部分を x と y 座標として文字列で返す具象メソッド
	public String touch(int x, int y) {

		return "x =" + x + "y =" + y;
	}
}

【具象クラス1】 抽象メソッドを2つオーバーライド「音通知」「東京時刻」に指定

public class AbstractTest2 extends AbstractTest {

	// 抽象メソッドをオーバーライド
	public String incoming() {
		return "音で通知";
	}

	// 抽象メソッドをオーバーライド
	public String time(int hour, int minuites) {
		return "東京の時刻は" + hour + "時" + minuites + "分";
	}

}

【具象クラス2】 抽象メソッドを2つオーバーライド「マナーモード通知」「アメリカ時刻」に指定

public class AbstractTest3 extends AbstractTest {

	// 抽象メソッドをオーバーライド
	public String incoming() {
		return "マナーモードで通知";
	}

	// 抽象メソッドをオーバーライド
	public String time(int hour, int minuites) {
		return "アメリカの時刻は" + hour + "時" + minuites + "分";
	}
}


抽象クラスの抽象メソッドは必ずオーバーライドしなければいけません。

 ※オーバーライド漏れしていると、コンパイラ―が知らせてくれます。

抽象クラスを元に別々の動作を持った具象クラス1 と具象クラス2 を作成しました。


抽象クラスのコンストラクタ

抽象クラスも「クラス」なのでコンストラクタを持っています。

抽象クラスを継承した具象クラスは、インスタンス生成時に抽象クラスのコンストラクタを呼んでいます。

抽象クラスのコンストラクタは通常の継承時と同じく super で呼ぶことができます。

 ※親コンストラクタの呼び方はコンストラクタ紹介の記事で詳しく紹介していますので、

  まだ知らないという方はご一読ください。

上記サンプルコードの「抽象クラス」と「具象クラス」にコンストラクタを足してみましょう。


◆抽象クラスのコンストラクタ呼び出し例

【抽象クラス】 引数ありのコンストラクタ追加

public abstract class AbstractTest {

	// 引数ありのコンストラクタ追加
	public AbstractTest(String str){
		System.out.println("抽象クラスのコンストラクタ" + str);
	}

	abstract String incoming();

	abstract String time(int hour, int minuites);

	public int charge(int num) {
		return num += 1;
	}

	public String touch(int x, int y) {

		return "x =" + x + "y =" + y;
	}
}

【具象クラス1】 super で親コンストラクタの呼び出し

public class AbstractTest2 extends AbstractTest {

	// 引数ありのコンストラクタ作成。親コンストラクタ呼び出し
	public AbstractTest2(String str) {
		super(str);
	}

	public String incoming() {
		return "音で通知";
	}

	public String time(int hour, int minuites) {
		return "東京の時刻は" + hour + "時" + minuites + "分";
	}
}


抽象クラス間の継承

抽象クラス同士でも継承は可能です。

抽象クラスから抽象クラスへ継承した際、抽象メソッドのオーバーライド(具象化)は任意となります。

継承先の抽象クラスで抽象メソッドをオーバーライドすることもできますし、

抽象クラスでオーバーライドせずに具象クラスでオーバーライドすることもできます。

ただし抽象メソッドは必ず具象化しなければならないため、

どちらの方法を実施するにしてもオーバーライド忘れには気を付けましょう。


◆抽象クラス間の継承例

【継承元の抽象クラス】

public abstract class AbstractTest {

	abstract String str();

}

【継承先の抽象クラス】 抽象メソッドのオーバーライドが無くてもエラーにならない

public abstract class AbstractTest2 extends AbstractTest {
}



インターフェースとの違い

抽象クラスは具象メソッドなどを持つため、実体があります。

そのため多重継承ができず、インターフェースとの大きな違いとして挙げられます。


他インターフェースとの違いは以下のような点になります。

抽象クラスとインターフェースの違い

 ※インターフェースは Java8 から新たにdefault メソッドと static メソッド機能が実装されたことにより、

  具象メソッドが持てるようになりました。



まとめ

抽象クラスは具象クラスが持つ共通メソッドを1つにまとめる役割を持ちます。

抽象クラスが抽象メソッドを持つ事で、メソッド名の統一やオーバーライド漏れを防ぐなど、

特にチーム開発で活躍する機能ですので、学習中の方はぜひ今の内から使えるようにしておきましょう。


関連記事リンク

インターフェースの紹介 / 継承とオーバーライドの紹介 / コンストラクタの紹介 / メソッドの紹介 / インスタンスの紹介 / アクセス修飾子の紹介


【著者】

若江

30代で異業種となるIT業界へ転職した駆け出しのプログラマです。これまで主に Java や Ruby、HTML/CSS を使って学習を目的としたショップサイトや掲示板サイトの作成を行いました。プログラマとしての経験が浅いからこそ、未経験者の目線に近い形で基礎の紹介をしていきたいと思います。

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様