Javaプログラミングを勉強しています。
抽象クラスについて疑問を持ちました。
結論から言うと、
・抽象クラスって必要でしょうか?
・現場でそんなに使っているのでしょうか?
抽象クラスの特徴としては以下の認識です。
・インスタンス化できない。
・サブクラスに継承することを前提に作成される。
・抽象クラスで宣言された抽象メソッドは継承されたサブクラス側で必ずオーバーライドされなければならない。
その結果、メリットは以下の2点であると思われます。
・サブクラス定義時にメソッドに間違いがあればコンパイルエラーが起き、コーディングミスを避けられる。
・複数のクラスで共通の名前や呼び出し方をもつメソッドは抽象クラスで抽象メソッドとして宣言しておき、それをサブクラスで実装させるようにできる。
たしかにこの2点がメリットではあるけれど、現場でそんなに使っているのでしょうか?
共通で使うなら、具象クラスにメソッドを定義してそれを複数のクラスに継承する方がサブクラスのコード量も減って便利なのかなとおもいます。
現場で抽象クラスをよく使う方がいれば、その目的、使用方法、メリットをお伺いできればと思います。
また「現場ではあまり使わない」と言った生の声もお待ちしています。
もしアドバイス頂ける方がいればよろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答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
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
総合スコア124
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
はじめまして。
java歴は浅いですが回答します。
自社開発の現場ではあまり使いませんが、似たような計算、処理を繰り返すことが事前に分かっている時にあえて作成することがあります。
また、それなりの規模の案件で外部の人間が入ってくる場合に間違えを減らす為作成することもあります。
私はソースコードが増えてしまうという理由で、ほとんど使用しませんが、エラー箇所を減らすという意味では使用した方が無難かと思います。
投稿2015/09/15 06:43
総合スコア658
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

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
総合スコア43
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/09/15 08:36