.net column
.NET開発者のためのブログメディア

Javaのabstractで抽象クラスを活用しよう!|@Overrideについて知ろう

2020年09月28日
SE
Javaのabstractをまだうまく使いこなせません。
PM
初心者のうちは、難しく感じるかもしれませんが、abstractを使いこなすために少し詳しく解説いたしましょう。

Javaのabstractとは?


Javaの初心者はabstractという修飾子についてよくわからない人もいるでしょう。abstractは抽象クラスを作るために必要なJavaの機能です。抽象クラスはその名の通り抽象的で、難しそうに感じるかもしれません。

しかしここでは難しいお話は避けて、とりあえずabstractを便利に活用することを目的に解説します。abstractで出来る事について知りたい人は是非ご覧ください。

抽象クラスの例

まずは実例を見てみましょう。以下のJavaサンプルをご覧ください。

abstract class Book {
public abstract void read();

public abstract void show_info();

public void remove() {
System.out.println(“”この本を削除します。””);
}
}

class Comic extends Book {
@Override
public void read() {
System.out.println(“”漫画を読みましょう。””);
}

@Override
public void show_info() {
System.out.println(“”これは漫画です。””);
}
}

抽象メソッドのサブクラスはオーバーライド必須

このJavaサンプルでは、Bookクラスを継承してComicクラスが作られています。Bookクラスには3つのメソッドがありますが、そのうちreadとshow_infoにはabstractがついていて、中身がありません。これを抽象メソッドと言います。

親クラスを継承(extends)した子クラスは、親クラスの抽象メソッドを必ず同じ名前で全て記述する必要があります。仮にComicにreadやshow_infoが無いと、エラーになるのです。

@Overrideはとても便利

Comicクラスのreadやshow_infoのように、親クラスと同じ名前のメソッドを記述することをオーバーライドと言います。それぞれに@Overrideがついていますが、これはアノテーションと言って、この場合はオーバーライドのメソッドであることがわかります。

@Overrideは必須ではありませんが、これがついていると、もしメソッドの名前を間違えた場合は「そのようなメソッドは親クラスにありませんよ」と警告を出してくれます。オーバーライドの間違いが防げるのでとても便利です。

抽象クラスはインスタンス化できない

話を抽象クラスに戻しますが、abstructの抽象メソッドが1つでもあるクラスは、クラス宣言でabstract classとして抽象クラスにする必要がありますそして抽象クラスはnewでインスタンスにすることができません。

Book b = new Book();

このJavaサンプルの場合、上記のようにしてもエラーになります。抽象クラスというのは子クラスのベースとしてとして使われるものだからです。

ただし下記のようであれば大丈夫です。

Book b = new Comic();

抽象クラスでメソッドの記述を強制する

抽象クラスはなぜ必要なのでしょうか。抽象クラスは「このメソッドは子クラスに必ず記述して欲しい」という時に使用します。

このJavaサンプルの場合、本のクラスは必ずreadメソッドとshow_infoメソッドをオーバーライドして記述して欲しいという意図があります。

必ず記述することで具体的にどのように役に立つのでしょうか。それを解説するので、まずここまでのJavaサンプルに以下を追加しましょう。

import java.util.*;

class Novel extends Book {
@Override
public void read() {
System.out.println(“”小説を読みましょう。””);
}

@Override
public void show_info() {
System.out.println(“”これは小説です。””);
}
}

public static void main(String[] args) {
ArrayList<Book> l = new ArrayList<Book>();
l.add(new Comic());
l.add(new Novel());
for(Book b : l) {
b.read();
}
}

抽象メソッドは一括処理で便利

上のJavaサンプルでは新たにNovelクラスを追加し、mainメソッドではBook型のArrayListクラスを生成してComicクラスとNovelクラスを追加しています。ArrayListはBook型なのでその子クラスを入れることができるのです。

そして拡張for文でArrayListの中のクラスのreadメソッドを呼んでいます。結果は以下になります。

漫画を読みましょう。
小説を読みましょう。

Bookクラスの子クラスは必ずreadメソッドがあるので、このような一括処理ができるのです。抽象メソッドの便利さがわかってきたのではないでしょうか。

抽象クラスを親に持つ抽象クラス

以下のJavaサンプルのように、抽象クラスを親に持つ抽象クラスを作ることもできます。抽象クラスであれば、親クラスの抽象メソッドは子クラスでも抽象メソッドとすることが可能です。

abstract class EBook extends Book {
public abstract void read();

public abstract void show_info();

public void download() {
System.out.println(“”電子書籍をダウンロードします。””);
}
}

このサンプルの場合、Bookクラスを修正せずに機能を追加したい時には便利でしょう。

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

Javaには抽象クラスに似た機能でインターフェイス(interface)があります。インターフェイスは抽象クラスと違い、全てのメソッドを抽象メソッドにする必要があります。ただしJava8からはdefault修飾子で普通に処理を記述できるようになりました。

さらにインターフェイスは抽象クラスと比較して、メソッドは全てpublicのみ、フィールドは全てpublic static finalの定数扱いになる、抽象クラスと違っていくつでも親クラスとして持てるという違いがあります。

なお正確にはインターフェイスは親クラスに持つとは言わず、実装(implements)すると言います。

抽象クラスをインターフェイスに置き換えてみる

ここまでのJavaサンプルを抽象クラスではなくインターフェイスで書き換えると以下のようになります。

interface Book {
public void read();

public void show_info();

public default void remove() {
System.out.println(“”この本を削除します。””);
}
}

class Comic implements Book {
@Override
public void read() {
System.out.println(“”漫画を読みましょう。””);
}

@Override
public void show_info() {
System.out.println(“”これは漫画です。””);
}
}

class Novel implements Book {
@Override
public void read() {
System.out.println(“”小説を読みましょう。””);
}

@Override
public void show_info() {
System.out.println(“”これは小説です。””);
}
}

抽象クラスとインターフェイスはどちらを使うべき?

mainメソッドはそのままで同じように動作します。このことからも抽象クラスとインターフェイスがとても似ていることがわかるでしょう。

では抽象クラスとインターフェイス、どちらを使用した方がよいのでしょうか。答えは、インターフェイスです。抽象クラスは1つしか親に持てませんが、インターフェイスはいくつでも実装できるという点が大きいですね。

Java8以前のインターフェイスはdefaultが無かったので、抽象クラスは普通の処理も記述できるというメリットがあったのですが、defaultが導入されたのでその差もなくなりました。

SE
抽象クラスとインターフェイスの違いや置き換え方などよくわかりました。
PM
Javaのスキルを高めるためにも抽象クラスの考え方を理解することはとても重要です。

抽象クラスの概念を知ってJavaのスキルを高めよう

Javaのabstructによる抽象クラスの使い方を解説しましたが、ご理解できましたでしょうか。

抽象クラスよりインターフェイスを使う方が望ましいのですが、抽象クラスの考え方を理解するためにも抽象クラスを是非使ってみましょう。使用することでオブジェクト指向プログラミングのスキルが高まるのは間違いないでしょう。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)