質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.42%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

意見交換

クローズ

4回答

1061閲覧

Javaの抽象クラスとインタフェースの使い分け

ymymymymy

総合スコア9

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

2クリップ

投稿2023/05/31 11:37

0

2

Javaの抽象クラスとインタフェースの使い分け

抽象クラスとインターフェースの違いについてある程度理解できたのですが、
実際にどういったシチュエーションで用いられるのか、その区別がつきません。

例えば、
抽象クラスは抽象メソッドに加え、具象メソッドを記述でき、
インタフェースにおいても、defaultを用いれば処理を書ける、
のであれば、抽象クラスで出来ることがインタフェースを使っても実現できる、と思うのです。

抽象クラスとインタフェースで、修飾子や多重継承などの違いがあることは理解できたのですが、
具体例が思いつかなくて、現状の理解度に満足していません

この機能を抽象クラスで実装しよう、インタフェースで実装しようと決めてになるのは、どういったシチュエーションですか?

具体的な例をあげてもらえると嬉しいです。

質問内容をまとめます

抽象クラスとインターフェースの具体的な利用方法は?

以上、よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答4

#1

episteme

総合スコア16614

投稿2023/05/31 11:51

編集2023/05/31 11:54

抽象クラスで出来ることがインタフェースを使っても実現できる、と思うのです。

だったら使い分けとか考えず、ぜんぶインタフェースにすればいい。
※ 昔のインタフェースはdefaultメソッドが書けなかったから抽象クラスが重宝されたけど。

ただし、インタフェースに定義するメソッドはすべてpublicになっちゃうから、
隠したいメソッドがあるときはアレですが。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#2

neko_the_shadow

総合スコア2285

投稿2023/05/31 15:53

個人的な見解ですが、インターフェースは"定義"のために利用します。たとえば製品情報を検索するサービスがあるとします。このサービスの利用者は製品情報がDBで管理されているのか、CSVファイルで管理されているのか、そういった具体的な実装については気にする必要はありません。利用者の関心はあくまで「製品IDを渡せば製品情報が取得できる」「すべての製品情報を取得できる」といったサービスのふるまい・定義にあります。

java

1public interface ProductSearchService { 2 Product find(String productId); 3 List<Product> findAll(); 4} 5 6// 本番環境ではDBで製品情報を管理する。 7public DBProductService implements ProductService { ... }; 8 9// テスト環境ではCSVで製品情報を管理する。 10public CSVProductService implements ProductService { ... };

一方、抽象クラスは"共通処理"のために利用します。製品情報を検索するクラス(ProductSearchService)とユーザ情報を検索するクラス(UserSearchService)があるとします。このふたつのクラスでは「DBにSELECT文を発行し結果を取得する」という処理が共通しています。この共通処理を抽象クラスに実装し、アクセス修飾子をprotectedとすることで、ProductSearchServiceとUserSearchService以外で利用させないようにします。

java

1public abstract class AbstractSearchService <T> { 2 protected List<T> executeSelectQuery(String query) { ... } 3} 4 5public class UserSearchService extends AbstractSearchService<User> { 6 public List<User> findAll() { /** executeSelectQueryを利用した処理 */ } 7} 8 9public class ProductSearchService extends AbstractSearchService<Product> { 10 public List<Product> findAll() { /** executeSelectQueryを利用した処理 */ } 11}

ただ、現代的なJavaプログラミングにおいては、抽象クラスはほとんど利用されなくなっているというのが個人的な感想です(インターフェースは利用されている)。共通処理のために抽象クラスを利用すると書きましたが、処理の共通化のために継承を利用することは推奨されません。そもそも現代的なオブジェクト指向プログラミングでは継承そのもの利用を避ける傾向にあります。これについてはJavaプログラミングにおいてもっとも有名なベストプラクティス集のひとつ『Effective Java 第3版』において次のような章がありますので、参考にしてみてください。

  • 項目18 継承よりもコンポジションを選ぶ
  • 項目19 継承のために設計および文書化する、でなければ継承を禁止する
  • 項目20 抽象クラスよりもインタフェースを選ぶ

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#3

xebme

総合スコア1087

投稿2023/06/01 10:01

編集2023/06/01 10:53

#2 補足情報です。

Swing

Swingのパッケージにデフォルトの振舞いをもつ抽象クラスがあります。目的はエンドユーザーが自力で複雑な処理を書く負担を軽減するためです。

Template Method パターン

Template Method パターンでは、抽象クラスのfinalなメソッドが呼ばれると、その中で自身の抽象メソッドを呼びます。finalなメソッドは内部の制御の流れを固定します。サブクラスは抽象メソッドをオーバーライドして、ポリモーフィズムを実現します。

しかし関数型インターフェイスが登場してから抽象メソッドを関数オブジェクトで置き換えることが推奨されるようになりました。『Effective Java 第3版』 項目44 標準の関数型インターフェースを使う

抽象メソッドをオーバーライドするより関数オブジェクトをインジェクションするという意味のようです。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#4

momon-ga

総合スコア4820

投稿2023/06/06 06:44

基本的にはインターフェースでこまらないならインターフェースでいいと思います。

使い分けは、インターフェースや抽象クラスそのものよりも・・・
それを利用するメソッド

たとえば、
void someMethod(someInterface a)
なのか
void someMethod(someSubclass a)
なのかな気がします。

このときインターフェースを引数として受け取るのか、抽象クラスのサブクラスで受け取るのかは
拡張性と、担保している機能で変わると考えています。

具体的にいうと・・・・

インターフェースのメソッドはfinalにできないため、特定の実装が求められるときにオーバーライドされると困ってしまうことがあります。
これは委譲されて呼ばれればOKとはいえ、わざわざ不具合を混入させる可能性のある移譲を選択するよりはfinalなメソッドを提供する方がよいでしょう。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

最新の回答から1ヶ月経過したため この意見交換はクローズされました

意見をやりとりしたい話題がある場合は質問してみましょう!

質問する

関連した質問