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

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

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

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

Q&A

解決済

4回答

22001閲覧

抽象クラスはなぜ必要か?

k499778

総合スコア599

Java

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

0グッド

5クリップ

投稿2015/09/15 06:30

Javaプログラミングを勉強しています。

抽象クラスについて疑問を持ちました。

結論から言うと、
・抽象クラスって必要でしょうか?
・現場でそんなに使っているのでしょうか?

抽象クラスの特徴としては以下の認識です。
・インスタンス化できない。
・サブクラスに継承することを前提に作成される。
・抽象クラスで宣言された抽象メソッドは継承されたサブクラス側で必ずオーバーライドされなければならない。

その結果、メリットは以下の2点であると思われます。
・サブクラス定義時にメソッドに間違いがあればコンパイルエラーが起き、コーディングミスを避けられる。
・複数のクラスで共通の名前や呼び出し方をもつメソッドは抽象クラスで抽象メソッドとして宣言しておき、それをサブクラスで実装させるようにできる。

たしかにこの2点がメリットではあるけれど、現場でそんなに使っているのでしょうか?

共通で使うなら、具象クラスにメソッドを定義してそれを複数のクラスに継承する方がサブクラスのコード量も減って便利なのかなとおもいます。

現場で抽象クラスをよく使う方がいれば、その目的、使用方法、メリットをお伺いできればと思います。
また「現場ではあまり使わない」と言った生の声もお待ちしています。

もしアドバイス頂ける方がいればよろしくお願いします。

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

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

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

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

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

guest

回答4

0

ベストアンサー

抽象クラスやインターフェースなどOOPで登場する概念は、コードの共通化ができたりコード量が減らせたりするなど「便利だから存在する」と言うよりは、構築していくシステムの『概念』をより正確に定義しコードを分かりやすくするための概念です。また、Javaの進化と共にアノテーションで共有する概念を宣言したり、DIコンテナ等で共通する処理を注入するなど、別の手段が取れるようになってきているため、抽象クラスが登場する場面は減ってきていると言えそうです。(例:JUnitのTestCaseが@Testになった、等)

質問者さまがあげられたメリットを根拠に抽象クラスを採用すると、後々ロジックが入り組むでしょう。

では、「どういう時に抽象クラスを採用するか」、というと、本当に減ってきていると思います。抽象クラスを採用すると、20年前に出版されたGoFによる「デザインパターン入門」にも「できるだけ継承より委譲を採用せよ」という趣旨が書かれているくらい、コードを書く時に継承は避けるべきです。親のクラスの性質をまるまる引き継ぐような概念はそう多くありません。子クラスは親クラスの性質をちゃんと引き継いでいるか確認する必要が出てくるので、テスタビリティが下がりますし。

よくトランザクションの開始、終了タイミングを揃えるよう、昔は抽象クラスを使い、テンプレートメソッドパターンにしていました。しかし、近年は同様の事を実現するためにアノテーションを使います。トランザクションが必要なメソッドにアノテーションを宣言すれば、後はフレームワークがいいようにします。

では、『抽象クラスでなければならないようなクラスはどんなクラスか』というと、例えばJavaFXのNodeクラスがあります。このクラスJavaFXのコンポーネントの基底クラスで、シーングラフを構成するためのクラスです。シーングラフとは、ウィンドウ(シーン)上にレイアウト用のパネルやボタンを載せていく機構です。ボタンにしろテキストフォームにしろ、どのコンポーネントもどの位置にどんなレイアウトで表示するのか、という情報は共通に必要です。そういう基底クラスを定義するときに抽象クラスを採用します。
JavaFXに馴染みがないのであれば、HTMLのタグも似たようなものです。どのタグにもスタイルだったりCSSのクラス名を定義できますが、aタグはリンクになるなど具象的な機能を持ちます。そういう概念を表す場合、HTMLTagという基底クラスを抽象クラスとして定義し、AnchorTagなどの具象クラスはHTMLTagを継承するように設計するでしょう。

抽象クラスはそういう基底クラスを設計する時に登場する概念です。何度も繰り返しますが、そんな風に性質を引き継がないといけないような概念はそう多くないので、システムを構築するような場合はあまり登場しないのではないでしょうか。

投稿2015/09/15 07:32

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

k499778

2015/09/15 08:36

kompiroさん 回答ありがとうございます。 たしかに私も抽象クラスのメリットを根拠に抽象クラスを採用すると、あまりよくないんじゃないかなと思っていました。他によりいい方法があったり、ロジックが入り組んだりといったデメリットが考えられたからです。 そうなんですね。やはり概念的な部分が大きく、また日進月歩進化するプログラミング業界ではより良い手段が増えてきているため、使用する機会はどんどん減ってきているんですね。 そんな気はしていましたが、実際の生の意見を聞けて説得力が増しました。そのようなお話が聞けてよかったです。 わかりやすく、丁寧で、私の求めている回答を頂くことができました。 もちろん他のお二方も同様です。 感謝しています。ありがとうございました。
guest

0

現場でJavaを使ったことがないので教科書的なところだけ

Javaで使われる抽象クラス、インターフェースでの抽象メソッドはあるクラスが継承、実装したら必ずその機能が存在するということを保証するためにあります。
下のようなクラスだと、一つのメソッドの実装を継承で使い回すことはできません。
ガソリンを補給するのと充電するのとでは処理の内容が大幅に異なるからです。

抽象クラスにインスタンスが代入できたのだったら燃料補給ってやれば実際の処理は違っていても、燃料が補給されているということが期待できます。

Java

1abstract class{ 2 int 速度; 3 //普通のメソッド 4 void 加速(int 速度増分){ 5 速度 += 速度増分; 6 } 7 //抽象メソッド 8 abstract void 燃料補給(int 補給量); 9} 10 11class 電気自動車 extends{ 12 int 電池残量; 13 void 燃料補給(int 補給量){ 14 電池残量 += 補給量; 15 } 16} 17 18class ガソリン車 extends{ 19 int ガソリン残量; 20 void 燃料補給(int 補給量){ 21 ガソリン残量 += 補給量; 22 } 23}

投稿2015/09/15 07:02

_nyannyan_

総合スコア124

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

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

k499778

2015/09/15 07:14

ShotaKurodaさん 回答ありがとうございます。 なるほど。 ・実装したら機能が存在することの保証。(オーバーライドしないといけないという特徴を活かした) ・処理内容をもたない抽象メソッドだからこそサブクラスの処理の複雑さに対応できる。 といったことですね。 2点目は具象クラスにはできない内容なので感心しました。 たしかにこれだと抽象クラスだからこそって感じですね。 新しい視点を学ぶことができました。ありがとうございます。感謝しています。
guest

0

はじめまして。
java歴は浅いですが回答します。
自社開発の現場ではあまり使いませんが、似たような計算、処理を繰り返すことが事前に分かっている時にあえて作成することがあります。
また、それなりの規模の案件で外部の人間が入ってくる場合に間違えを減らす為作成することもあります。
私はソースコードが増えてしまうという理由で、ほとんど使用しませんが、エラー箇所を減らすという意味では使用した方が無難かと思います。

投稿2015/09/15 06:43

kpiyohiko

総合スコア658

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

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

k499778

2015/09/15 06:49 編集

kpiyohikoさん 回答ありがとうございます。 なるほど。やはり大規模プロジェクトや新参者が入ってくる場合は、メリットの2つが効いてくるんですね。 実際の具体的な使用頻度が気になるところではありますが、これは自分が肌で感じないとわからない部分かもしれませんね。 迅速な対応ありがとうございました。
kpiyohiko

2015/09/15 06:55

使用頻度ですが、会社や現場、規模に寄るとしかいえません;; 私が関わった中規模~大規模案件ではリーダーによって多用するチームとほとんど使わないチームとに分かれていました。 進捗の具合はやはり多用している方が出戻りが少ないので、優位でした。 ただ、ほぼすべてのタスクを把握している通称妖怪リーダーのチームはほとんど抽象クラスをほとんど使用していないのに出戻りが皆無でした… ここには私よりはるかに様々な経験をしている方がたくさんいらっしゃるので私も実際はどうなのか気になります!
k499778

2015/09/15 07:03

わざわざ追加回答ありがとうございます! そうなんですね。 確かにこればっかりはリーダーの気質にも寄ると思います。もちろプロジェクトの規模感や特徴も。 その感覚は自分で実際に体験してみないとハッキリとはしないものかもしれません。 とはいえ私もいろいろな意見は聞きたいのでもう少し他の方の意見も待ってみます。 ありがとうございます!
guest

0

私もJava歴はあまりありませんが、先日シリアル通信アプリを少々作ってみました。
通信の方は専用のクラスを作り、メインはGUIで表現することにしました。
そこで、通信の受信イベントで受け取った情報をGUI側に反映させるにはどうしたらよいのか悩みました。
その時初めてabstractクラスとそのメソッドを実装しました。

この方法があっているのかわかりませんが、通信クラスをabstractクラスにして、受信イベントの処理の部分にabstractメソッドを呼び出すようにしました。
その実装をメインのGUIクラスの方ですることにより、GUIの方に受け取った値を中継することができました。

Java

1/** 通信側のクラス */ 2public class 通信クラス implements 通信リスナー { 3 @Override 4 public void 受信イベント(Event event) { 5 受信処理(受信データ); 6 } 7 public abstract void 受信処理(String 受信データ); 8} 9 10/** GUI側のクラス */ 11public class GUIクラス extends 通信クラス { 12 private テキストボックス テキスト; 13 // 略 14 通信クラス() { 15 テキストボックス テキスト = new テキストボックス(); 16 } 17 @Override 18 public void 受信処理( String 受信データ ) { 19 テキスト.setText(受信データ); 20 } 21 // 略 22} 23コード

使い方があっているかどうかはわかりませんが、思い通りの動きをしました。
内容を抽象化するために日本語でクラス名やメソッド名を書いてみました。
具体的にはrxtxライブラリを用いたシリアル通信アプリですが、標準ライブラリにはない(ネット上には置かれています)ものですので、あえてこのように抽象化した記述をしてみました。

別にインターフェースで実装してもよいのでしょうが、今回は実装方法も決めていましたので、extends と implementsを同時に呼ぶ必要もないと考えたので今回はこのようにしました。
通信だけできる(継承されれば)クラスと描画もできるように拡張したクラスの継承関係ですね。

インターフェースは表面の繋がりを持たせるものなので、内部と外部をつなぐということでしょうか。
abstractクラスやインターフェースは概念が難しいですが使えば面白いこともできそうです。

では。

投稿2015/09/29 14:21

tttsak

総合スコア43

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問