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

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

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

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

Q&A

解決済

3回答

1906閲覧

抽象クラスだけが良くわかりません。

King_of_Flies

総合スコア382

Java

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

1グッド

3クリップ

投稿2017/10/26 05:25

お疲れ様です。

基底クラス、派生クラス、抽象クラスというクラス概念について学んでおります。

基底クラスは別目、スーパークラス、親クラスといい、
あるクラスの仕様を継承して新しいクラスを作成する際に、元となるクラスのこと。
【わかる。】

派生クラスは別名、サブクラス、子クラスといい、
基底クラスの仕様を継承して作成されるクラスのことで、
元のクラスに無い独自の部分だけを新たに定義・実装して作られる。
また、元のクラスで定義されているメソッドなどを上書き(オーバーライド)して独自のものに改変することもできる。
【わかる。】

抽象クラスは・・・・

http://www.atmarkit.co.jp/ait/articles/1003/30/news085.html

抽象クラスを使える3つの場面

 このクラスは、以下の3つの場面で使えます。

1.あるインターフェイスを実装するクラスを複数作成したところ、どのクラスにも共通の実装が必要なことが分かって、コードを共有化したい
2.クラスが実装するべきインターフェイスは決まっていて、一部については実装方法も決まっているが、全部の実装方法までは決まっていない
3.既存のクラスに、あるインターフェイスを実装することにして、基本クラスとして使いたい

 要するに、抽象クラスとは、「インターフェイスとクラスの中間のようなもの」で、基本的な処理の実装はできているが一部の処理はサブクラスが実装するようにさせたい場合に使います。

【?】

サイトの以降の記述も参考にコードを見ましたが、
良く理解できませんでした。

インターフェースはわかるのですが、
これはどういうメリットを享受できるものですか?

アバウトな質問で申し訳ないですが、詳しくお願いいたします。

yohhoy👍を押しています

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

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

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

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

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

ozwk

2017/10/26 05:29

「以下の3つの場面で使えます。 ~」がそのままメリットなんですが、何が理解できませんか?
King_of_Flies

2017/10/26 05:34

1.あるインターフェイスを実装するクラスを複数作成したところ、どのクラスにも共通の実装が必要なことが分かって、コードを共有化したい→親クラスに書けばいいのでは・・・?
King_of_Flies

2017/10/26 05:35

2.クラスが実装するべきインターフェイスは決まっていて、一部については実装方法も決まっているが、全部の実装方法までは決まっていない→実装方法が決まっていないってどういうことですか?実装方法が決まったら抽象クラスじゃなくなるんですか?
King_of_Flies

2017/10/26 05:36

3.既存のクラスに、あるインターフェイスを実装することにして、基本クラスとして使いたい →インタフェースを実装したクラスを親クラスとして使うということですか?
King_of_Flies

2017/10/26 05:56

あの。ここで質問が解決してしまった場合はBAをどうすればいいでしょう・・・・
King_of_Flies

2017/10/26 06:15

Youがその参考URLを回答に移してくれるのでしたらBAつけますYo!
guest

回答3

0

ベストアンサー

オブジェクト指向を真に強力にするのは抽象化なのですが、
同時に、非常に難しい部分でもあります。とくに継承は使い方が難しい。

ご質問でのメリットというのは、テンプレートメソッドパターンだと思いますが、
私はあまり使わないですし、おそらく全体でも、最近では使われる機会が少ないでしょう。

私自身が意識している原則はまず、「継承より委譲」ということと、
継承する場合でも、実装継承は避け、型継承だけするようにしています。
つまり、継承は実装の再利用ではなく、概念の分類に使います。

実装がないことに最初は魅力を感じないと思いますが、
慣れてくるとむしろ実装が邪魔にすら感じてきます。
抽象化には実装がない方が都合が良いのです。

かつての構造化技法がそうですが、抽象化ではなく、直接実装の共通化をしていて、
何が問題かというと、引数が多くなったり扱い方が煩雑になっていくんですね。
処理を共通化すると同時に、知らないといけないことも増えていく。
でも、抽象化すると、実装に引きずられず、型の共通化に専念できるんです。


ここまで、抽象的で意味が分かりにくいと思うので、日常の事物に喩えてみます。

抽象化の仕組みというのは、ある種の「無用の用」でして、
たとえば、マンションの共有部分、たとえばエレベータホールには、
住人の私物を置くなと。物がないから人が通りやすい。
公園も公共空間ですが、やはり私物は置かないようにしますね。

あるいは、パソコンにはたいてい、USB機器を差す穴が空いてます。
USBは規格ですが、穴だからいろんな機器を差せるわけです。
直接ハンダ付けしてしまうと、交換できなくなるんです。
この仕組みは文字通りの「インターフェイス」です。


プログラムに戻って、どんなときに継承の仕組みを使うかというと、
規格化したいときです。たとえば、特定のメソッドを必ず持たせたい場合。

そういう仕組みの何が良いのかというと、たとえば、
継承したクラスにはメソッドが例外なくあるから、
探さなくても使えるわけです。何万行、何十万行と規模が大きくなると、
実装を書く手間より、探す手間の方が大きくなっていくんです。
実装は十行だけど、探すのは十万行とか、そういうスケールの対比だから。

だけど、書いた方が早いっていうと、とくに複数人の開発だと、
同じような処理がバラバラに増えていって、ますますカオスになっていく。

だから、規模が大きいほど、実装より型の方が重要になってくるんです。
その型を決める仕組みが、抽象クラスとかインターフェイスです。

最後に、OOはわりと方法論が乱立しているので、学習が難しいですが、
自分で使いやすいと感じた言語仕様やライブラリ、フレームワークなどの
仕組みを研究すると、効果を実感しやすいと思います。

投稿2017/11/14 03:51

LLman

総合スコア5592

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

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

0

そもそも、「基底クラス、派生クラス、抽象クラス」は、同列で扱うものではないので、
ごちゃっとしてるのかもしれません。

・実装レベル(すでに理解されているようです)
基底クラス : 派生クラス
継承元、先の関係です。

・設計レベル
抽象クラス:具象クラス
オブジェクト指向は単純なライブラリのように使うのでなくオブジェクト間の関係性を再利用します。
※有名なやつだとデザインパターン
解決する問題や領域で、具体的な実装は異なるため、具象クラスでのデザインは確定できません。

あとは、調べてあるとおりなのですが。
・一部の実装は決まっているので、共通・共有化したい
・個別実装にまかせると困る部分があるので、事前に実装を固定化したい

というような、実装したいor実装せざるをえない場合、抽象クラスで部分実装します。

投稿2017/10/27 02:14

momon-ga

総合スコア4820

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

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

0

実際に使われた例がないとわかりづらいと思いますので、抽象クラスである、java.io.InputStreamを見てみましょう(JDK7)。

この abstract クラスは、バイト入力ストリームを表現するすべてのクラスのスーパークラスです。

InputStream のサブクラスを定義する必要のあるアプリケーションは、必ず入力の次のバイトを返すメソッドを提供しなければなりません。

実際に「入力の次のバイトを返す」方法はストリームの種類によって異なるので、InputStreamとして具体的に実装することはできません。一方で、このread()を実装すれば、InputStream標準のread(byte[])read()を使うことで実行できますので、何もしなくてもサブクラスで使えるようになります。

なお、Java 8からは「デフォルト実装付きのインターフェース」が導入されていますので、状況によってはそっちのほうが便利かもしれません(Qiita)。

投稿2017/10/26 05:58

maisumakun

総合スコア145121

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問