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

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

新規登録して質問してみよう
ただいま回答率
85.54%
オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

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

Q&A

解決済

17回答

76569閲覧

インターフェースって何のメリットがあるんですか?

mr0237

総合スコア164

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

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

6グッド

28クリップ

投稿2017/03/25 11:14

JAVAを勉強している者です。説明が下手ですいませんが、「インターフェース」って何のメリットがあるんですか?
インターフェース」は

派生化してその目的に特化したそれぞれのクラスを統一しておくことでそれらのクラスを気にしなくても、使うことができるもの

とか

派生化したそれぞれのクラスが、その中身を気にしなくても統一して利用できるようにするためのもの」(説明が下手ですいません。)

らしいですが、そんなことして何のメリットがあるんですか?開発が短縮されるんですか?

バラバラな(派生化してその目的に特化した)クラスを統一するなら、最初からきちんと完璧に設計すれば早いと思うのですがどうでしょうか?

**わかりやすいような例や例えで教えてくれませんか?  **

よろしくお願いします。

kousuketanihata, kackey01, Kama, xenbeat, eien_beginner, alinqo👍を押しています

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

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

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

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

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

guest

回答17

37

既に回答が出揃ってる感ありますが、少しでもお役に立てればと思ったので回答させていただきます。
僕も初学の際に同じような疑問を持っていたので、僕なりにわかりやすくお伝えできればと思います。

前提

以下のようなアプリケーションであればインターフェースを利用するメリットはほとんどありません。

  • 一人で開発するアプリケーション
  • 一度作って終わる(作った後一切変更をしない)アプリケーション
  • レイヤ化(MVC等)する必要のないアプリケーション

故に、上記に当てはまらないアプリケーション開発をイメージして説明させていただきます。
(ほとんどこのケースですが・・・)

説明

何のメリットがあるんですか?

インターフェースの実装が増えても利用者はそれを意識せず形式的に利用できるというメリットがあります。
詳細は、例を踏まえて後述します。

開発が短縮されるんですか?

上記のメリットがあるので、長期的な目線で見ると短縮されることがあります。
ただし、一度作って終わるものはファイルを余計に作成するだけなので逆に開発が延びます。

バラバラな(派生化してその目的に特化した)クラスを統一するなら、最初からきちんと完璧に設計すれば早いと思うのですがどうでしょうか?

将来的に起こりうる変更を予測して、おっしゃるように「最初からきちんと完璧に設計」できるのであれば、それに越したことはありません。

わかりやすいような例や例えで教えてくれませんか?

一般的に、インターフェースとは「契約」と言われることが多いです。
日常生活で身近な契約って何だろて考えたときに、電力会社との契約とかがわかりやすいかなと思います。
電力会社と契約済みであれば、極端ですが「電気ちょーだい」というと電気が供給されると思います。
この時、供給された電気はどこでどのように生み出されたのか意識したことはありませんよね?(原子力発電なのか、火力発電なのか、風力発電なのか)
そして、もしかしたら、将来的に原子力発電は廃止されて、それに変わる新たな発電方式が生み出されるかもしれません。その場合でも今まで通り「電気ちょーだい」というと電気が供給されるはずです。
このように、**利用者は、契約(インターフェース)によって、電源(実装)を意識しなくても、形式的に電気(メソッド)を利用することができます。**これがインターフェースの主な存在意義だと思います。

では具体的に、その考え方がどのように実装に活かされるのかを、簡単な例になりますが見ていきましょう。
TODO管理のアプリケーションをチーム(複数人)で開発する場面を想像してみてください。

  1. まず、TODOのデータを保存する場所を考える必要がありますよね。

最初は、開発スピード等を重視して、この保存先にローカルのファイルを選んだとしましょう。
0. 次に、少なくともリクエストをコントロールする「クラスA」と、ローカルのファイルに対してTODOデータをCRUDする「クラスB」を実装すると思います。
※ここでは「クラスA」と「クラスB」との間にインターフェース(契約)を設けないでアプリケーションを作り上げたとします。
0. リリース後、ユーザーが順調に増え、アプリケーションがまともに動かなくなってきました。
0. スケーラブルな構成への変更を余儀なくされ、データの保存先をローカルのファイルから、クラウドのRDBMSへ移行することを決めます。
0. そして、誰かがRDBMSに対してTODOデータをCRUDする「クラスC」を実装しようとします。

ここからが悲劇の始まりです。
過去に誰かが実装した「クラスA」は「クラスB」からデータをもらう前提で実装されています。
今回の変更で「クラスA」は「クラスB」ではなく「クラスC」からデータをもらうことになるので「クラスC」の実装・テストに加え「クラスC」の実装を知った上で「クラスA」の修正・テストも必要になります。
せっかく責務を分離してクラスを分けていたのに、結局クラスAへの影響も大きそうですね。。。

もし、最初から「クラスA」と「クラスB(TODOデータをCRUDするクラス)」との間にインターフェース(契約)があれば、今回も「クラスC」がそのインターフェースを実装することによって戻り値の型は保証されるので「クラスA」は「クラスC」の実装を知る必要がありません。
そして多くの場合「クラスA」にほとんど影響はありません。
また、この先NoSQLに対してCRUDを行う「クラスD」、新型のDBに対してCRUDを行う「クラスE」・・・が現れても「クラスA」と「TODOデータをCRUDするクラス」との間にインターフェース(契約)があるかぎり「クラスA」はそのクラスの実装を全く意識する必要はありません。
「クラスA」は「クラスB〜E・・・」がどんな実装をしてどこからデータを取ってこようが、それらのクラスが契約通りに実装してくれれば「クラスA」に変更が加わることは原則ありません。

以上、簡単な例でしたが前述の通り、役割ごとにカテゴライズされた各レイヤー間にインターフェース(契約)を設けることによって、各レイヤー間を疎結合にし(依存度を低くし)、変更に強いアプリケーション作ることができる
これがインターフェースを利用する最大のメリットと言っても過言ではないと思います。

#####補足
インターフェースのメリットを最大限に活かす仕組みとしてDependency Injection(依存性の注入)というデザインパターンがあります。
少々複雑な上、質問に対する回答にはならないのでここでは触れませんが、インターフェースを理解された次のステップとして、知っておくと良いと思います。

投稿2017/03/25 21:22

編集2019/02/16 18:39
xenbeat

総合スコア4258

Alupi, suzunox, TAONE, yuba, kiahi39, nakanishi_h, Gonta616, hotta, y-kissy, tetejiro, 他27名👍を押しています

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

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

yuba

2017/03/26 00:07

以前、エンジニアのレベルを問う質問の1問目として「インターフェースのメリットを一言で説明せよ」というのを挙げておられた方がいて、その方の模範解答が「疎結合の実現」だったなというのを、補足でDIに触れられているのを見て思い出しました。 http://d.hatena.ne.jp/iad_otomamay/20130318/1363596244
MasahikoFukui

2017/03/28 05:44 編集

すみません。 書くところ間違えました。
guest

21

ベストアンサー

未来のことを考えてください。

今完璧に設計しても、世の中の法律が変わるとかお客さんの要望が変わるとか、さまざまな要件でコードには見直しがかかるときがあります。
インターフェースとはそのときに備えておくためのものです。
こちらが参考になるかもしれません。

ここから具体例を書いてみましょう。長くなりますので読まなくても構いません。

家電製品を考えてみます。

【問題になるようなパターン(インターフェースなし)】

1.ドライヤーを作った
2.電子レンジを作った
3.冷蔵庫を作った

それぞれは共通のコンセントを持っていますので、一つの電源タップで利用することができるとします。

4.新しい電化製品、テレビが発明された。

ここでこのテレビという製品は、新製品であるがためにコンセントの形が独自に作られていたとします。
そうすると従来の電源タップで使うことができません。変換機を買ってきたり、場合によっては家を工事する必要があるとします。
せっかくの新製品なのに、うまく使えず家庭の皆さんはさぞ怒ったことでしょう。また売るほうとしても工事が必要とあっては売れ行きに響くかもしれません。

これがインターフェースが統一されていないということです。

【上記問題を解決するようなパターン(インターフェースあり)】

0.コンセントの規格が決まり、電化製品は基本的にはその規格に沿ったコンセントを作る必要があることになった(インターフェース)
1.ドライヤーを作った
2.電子レンジを作った
3.冷蔵庫を作った
4.テレビが発明された

ここで上記の家電製品のコンセントの形が全て統一されていれば、全て同じ電源タップが使えますね。変換機を買ってきたり、工事をしてコンセントの形を変えたりなどということは不要になります。
逆に言えば、家電製品の開発者は「コンセントの形を統一する必要性に迫られる」ということになりますが、それがインターフェースの本質です。

CDを買ったことはありますか?いろんなレコード会社から出ているCDは、統一されたCDプレイヤーで聴くことができますね。それはCDというインターフェースに合わせて各会社がCDを作っているからです。何もCDプレイヤーを買いなおす必要はないわけですが、それは各会社がわざわざ努力している賜物です。
AndroidとiOSは充電に使うケーブルの形が違いますね。あれは規格が違うからです。ユーザーからすれば、統一されていたほうが便利だと思いませんか。企業戦略ゆえ仕方のないことですが、2本も使い分けしたりしたくはないですね。

投稿2017/03/25 17:40

akabee

総合スコア1947

yuba, thesnowman, stereo_code, swordone, kousuketanihata, hsk, tsunex, musix55, KotaroYamame, palm-t, 他11名👍を押しています

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

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

4

実は僕も、(欠点は多いですが)「多重継承でいんじゃね?」と思ったことがあります。

まずインタフェースのインプリメントと、クラスの継承の違いから考えると。
クラスの継承は、そのクラスの本質的な機能を受け継ぐことです。
対して、インタフェースの実装はそれ以外の機能を参照するための「口」を作ることです。

実のところ、デリゲーション(移譲)モデルを理解しないで、インタフェース継承だけ使っても旨味は薄いです。
というか、C++の多重継承とどう違うのかさえ理解しづらいです。

さらに言えば、インタフェースは継承した側から見れば「機能の拡張」ですが、参照する側から見れば余計なメソッドや属性をいじらせないための「機能の制限」(=他の人のコメにも書いてある通り「疎結合」ってやつですね)と言う側面もあります。まさに「インタフェース」です。

そういった事が理解できた頃から「なるほど合理的だ」と思えてきたものです。

投稿2017/03/28 05:41

編集2017/03/28 05:46
MasahikoFukui

総合スコア18

i50, sheephuman, tf2014, real👍を押しています

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

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

4

javaの入門書を読んでいた時は私も同じようなことを思っていました。
インタフェースって何の意味あるの?使うことあるの?

時は経ち、初心者ではなくなって、色んなライブラリやフレームワークを使っているうちに、
インタフェースって便利、と思えるようになりました。

実例がないと理解しづらいですが、初心者のうちは実例を理解できるレベルにないと思うので、
理解に時間がかかりそうなところは読み飛ばして、
経験を積んだ後に読み返してみると、スッと入ってくると思います。

投稿2017/03/25 17:58

lightwill

総合スコア962

stereo_code, masatoru, AkiraIrifune, KSwordOfHaste👍を押しています

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

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

3

私の答えは恐らく少数派で、反論が出ると思いますが... Jave,C#は多重継承がないのでインターフェイスが必要だったのではないかと考えています。逆に、多重継承があれば、インターフェイスは要らなかったのではと考えています。

コンセントの例でしたら、抽象クラスでも同じことが出来るわけですし。なぜ、Javaに多重継承がないのかが疑問です。

投稿2017/03/28 04:22

tf2014

総合スコア75

AmaiSaeta, i50, tsunex👍を押しています

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

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

tsunex

2017/03/28 05:37

自分はこんなイメージで認識してます。 抽象クラス  家電とコンセント  家電にはいろんなものがありますがコンセントは基本同一 インターフェース  ネジと多機能ドライバー  ドライバーの先端はねじにあったものに交換
xenbeat

2017/03/28 06:19 編集

>Jave,C#は多重継承がないのでインターフェイスが必要 C#はわからないですが、Javeに限っては違うと思います。 >なぜ、Javaに多重継承がないのかが疑問です。 「James Arthur Gosling」が、多重継承の複雑な問題、多重継承があってもほとんど使用されないという理由から機能を省略したと、JavaのOverviewで明言しています。 http://www.cs.dartmouth.edu/~mckeeman/cs118/references/OriginalJavaWhitepaper.pdf Javaにおいて、多重継承の機能を省略することは欠陥ではなく、実装者にとっては良いことだと考えます。
akabee

2017/03/28 07:00 編集

私も議論に参加したくなりました。 抽象クラスはインターフェースより自由度が高いイメージですね。 家電製品とコンセントの例で抽象クラスを引き合いに出すのであれば、一つの家電製品を作るときに抽象クラス「家電製品」を継承しその中の抽象メソッドの一つに「コンセント」があるか、インターフェース「コンセント」を継承するかの違いと言えるのではないかと思います。 インターフェースのほうが制約が大きいのですが、プログラミングの世界では制約が大きいことによるメリットも大きいですから、要は使い分けだと思います。 Javaに多重継承がない点についてですが、オブジェクト志向的にも多重継承は微妙なんですよね。。「多重継承を使いたい」というような状況は、残念ながら、クラス分けがしっかりできていない状況に該当していると思います。Javaに多重継承が無いということと関連があるかないかは分からないのですが。 家電製品の例を引っ張って申し訳ありませんが、例えば勉強机とかこたつとか、家具と分類されるようなものにもコンセントがある場合がありますよね。 そういう場合にクラス「家具」と「家電製品」を多重継承するのは、なんだか家具に必要ない家電製品の機能までたくさんついてきそうじゃないですか? であれば、コンセントが必要な家具であれば抽象クラス「家具」を継承した上でインターフェイス「コンセント」も必要であれば実装すればいい。勉強机には電気を付けられるものもありますから、コンセントの他にも追加で「電気取り付け具」や「電気のスイッチ」も付加すればいい。そういう実装であればJavaも認めています。 私は上記のような理解をしています。
tknakamuri

2017/03/28 14:45

今のJavaは制限付きで多重継承できますよ。 Java8からです。
tf2014

2017/03/29 04:12

Original Java Whitepaper を流し読みしてみました。 2ページに確かに「よく理解されていない、タメにならずダメになるC++の機能は削除した。」と書いてあります。 多重継承がないことが良いことという決断に基づきJavaを製作を進めてたら、困ることに気づいた。そこで、インターフェイスというキーワードを作った…とは考えられないでしょうか? 以上は、ロバート・マーチンの講習での話しに基づく私の推測ですが、マーチン自身ブログで「インターフェイスの存在はJava製作者の怠惰だと推測する」と書いています。 http://blog.cleancoder.com/uncle-bob/2015/01/08/InterfaceConsideredHarmful.html 更に、マーチンは言語の製作者は開発者を 多重継承できないと制約することでなく、多重継承するかどうかは開発者の自由であるべきで、開発者が責任を持つべきだといった内容を話していました。 以下の抽象クラスは、多重継承が出来ないことを除いてはインターフェイスとまったく同じことを達成できます。 public abstract class Consent{ public abstract void SupplyPower(); } abstractキーワードがあるのでSupplyPower関数はオーバーライドされなくてはならない。つまり、インターフェイスで定義されたメソッドは定義されなくてはならないことと同意。 public interface Consent{ public void SupplyPower(); } ...と書きましたが、私自身インターフェイスは多用するし、依存性の注入でも、抽象クラスでなく、インターフェイスを注入します。理由は、コーディング・スタンダードがインターフェイスという機能があることに基づいて進化した、他の開発者と同じスタイルを取り、読みやすいコードを目指すこと、Akebeeさんが書いたように「インターフェースのほうが制約が大きいのですが、プログラミングの世界では制約が大きいことによるメリットも大きいですから、要は使い分けだと思います。」に合意するからです。 ちなみに、コンセント(ソケットの形状を複数の電力会社で「合意」して決めた consent plug)はインターフェイス=「継承したメソッドを定義するという契約」に合意するという例としよく分かりやすいものだと思います。
MasahikoFukui

2017/03/29 08:46 編集

多重継承が複雑な問題を(主に型変換で)引き起こすのは周知に事実として、 実例はみなさん書いているおられるようなので、ちょっと余談を... 昔のオブジェクト指向フレームワークって継承だけで全てを構築しようという姿勢で作られていたんですよ。多重継承でなんでも取り込むみたいな。 それから90年代中頃になると、それらのフレームワークもデリゲーションモデルを取り入れるようになって、実装とインタフェースのクラスを分けて作るようになるわけです。インタフェースがないので結局は多重継承なんですが(^^;) ちなみにJavaのフレームワークにもそういった継承万能主義の名残がありますよね。 コンポーネントにマウス操作のハンドラが残ってたりとか。あの頃は仕様を見ただけで実用に耐えないフレームワークだと思っていたけど、程なくイベントリスナ(インタフェース)を使ったイベントメカニズムが登場しました。 そんなわけで、なぜインタフェースで十分かを知るにはデリゲーション(移譲)モデルを理解すると良いでしょう。実感できますよ。 結局、デリゲーションモデルを使うと、継承するのはそのクラスの本質的な機能を持つ御先祖様だけで、それ以外の機能の口はインタフェースを継承して、処理方法を知っている他のクラスのインスタンスを作って右から左に流してやる感じで間に合っちゃうんですよ。
guest

3

例:コンセントとプラグ

世の電源プラグが規格がバラバラだったとして、

この部屋のコンセントは、とある掃除機の電源プラグにしか適合しません。
別の部屋のコンセントは、とあるテレビの電源プラグにしか適合しません。

などと言われたら不便ですよね?

そこで電源プラグにインターフェースを定義してやれば
コンセント側は何が刺さっているかは気にせずに電力供給できるようになりますね。

もちろん最初からちゃんと"設計"して、ここにはこの機械しか置かないと決めれば
インターフェースがなくても問題ないですが、
これが賃貸住宅などだったら柔軟性がなくて使う側が困りますね?

基礎的な仕組みだけ提供し、後は使う側が決めてくださいというときに
インターフェースは役立ちます。
プログラム的には、フレームワークなんかがそうですね。


例:加速度センサーをつかって歩数計を作る

加速度センサークラスなるものが存在するとして、
歩数計クラスは加速度センサークラスから値を取ってきて
いろいろ処理して歩数を計算するとします。

さて、不具合が起きたときの調査用に、
加速度センサーのログを模擬入力として歩数計を動かしたく思いました。

安直なのは歩数計クラス内に、

if(調査モード) acc = ログファイル.値を取ってくる(); else acc = 実機.値を取ってくる(); (歩数判定の処理)

などと書くことです。

しかし、これだと、歩数計クラスが歩数判定以外のことをしてしまい、コードの見通しが悪くなります。

そこで、加速度センサーインタフェースを作成し、
実際のセンサーと、ログファイルによる模擬はこのインターフェースを実装させます。

歩数系クラスはインスタンス作成時に
加速度センサーインタフェース(を実装したクラスのインスタンス)を渡せば

acc = センサー.値を取ってくる(); (歩数判定の処理)

と歩数計クラス内で歩数検知に関係ないコードが減ります。

投稿2017/03/25 13:00

ozwk

総合スコア13502

i50, tf2014, KSwordOfHaste👍を押しています

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

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

yuba

2017/03/26 00:10

実例のほう、これはインターフェースのメリットではなくて段階的詳細化というか責務を関数にまとめることのメリットについてのものになるかと思います。
ozwk

2017/03/26 01:33

歩数検知と加速度取得の具体的な方法をDI的に切り離す例のつもりだったんです。
guest

2

ざっくりと説明すると、サービスを提供する側(ライブラリーなんかがそうですね)が、

「うちのサービスを使うときには、この『資格』を満たしてね!」

ということを、あらかじめ決めておくための仕組み、
って感じですかね。

資格を満たす=規定されたメソッドを実装する。

ですね。

同じようなことは、もちろん、クラスの派生でもできるんですが、
インターフェースのほうが、使いやすい場面があるということなんですね。

ちょっと、例え話での説明に挑戦してみます。

すべての動物が参加できる、オリンピックが開催されるとします。
それをシステムとして考えてみましょう。
(なんて例えだw)

オリンピックなんで、幾つもの競技があります。
100m走、水泳なんかは、人間界にもありますが、
全動物ですから、飛行競技だってあったりします。

100m走に出場するため『資格』は、「走れる」ことで、
(走る)という行動が取れることです。
水泳に出場するための『資格』は、「泳げる」ことで、
(泳ぐ)という行動が取れることです。
飛行競技に出場するための『資格』は、「飛べる」ことで、
(飛ぶ)という行動が取れることです。

オリンピック運営側(サービスを提供する側)は、
各競技ごとに必要な『資格』をあらかじめ決めておくことで、
どんな動物が出場できるかを提示することができますよね。

さて、次は、参加動物(サービスを利用する側)について。

それぞれの競技に参加できるのは「どんな動物か?」
「走れる」動物、「泳げる」動物、「飛べる」動物です。

鳥や、魚や、四足歩行、二足歩行、なんかで分類しようとすると、
ちょっと無理がありますよね。

例えば・・・

魚であるトビウオは、水泳に参加できる。
魚であるトビウオは、飛行競技にも参加できる。(ちょっと違うくない?w)
鳥であるワシは、飛行競技に参加できる。
ペンギンやダチョウは、鳥なのに、飛行競技に参加できない。(なんてこった)
四足歩行のチーターは、100m走に参加できる。
二足歩行のヒトも、100m走に参加できる。
鳥であるダチョウは、100m走には参加できる。(おお!)
鳥であるペンギンは、100m走には参加できる。(参加することに意義あり!)
鳥であるペンギンは、水泳にも参加できる(おお!!)

さあ、鳥はどうやって分類(汎用クラス)しましょう?
飛べる鳥、
飛べない鳥、
飛べないけど泳げる鳥、
飛べないけど走れる鳥、
飛べないけど走れて泳げるペンギン(笑)

もう、抽象化の意味がなくなってきそうですw

そこで、『資格』(インターフェース)ですね。
『資格』を特徴として考えて、

鳥「飛べる」
鳥「走れる」
鳥「走れる」「泳げる」

というように、より抽象的な鳥クラスを、それぞれの『資格』(インターフェース)で補足するほうが、
表現しやすそうです。

ペンギンは、鳥で、「走れる」「泳げる」『資格』を実装しているわけです。

さて、話をオリンピック運営側に戻します。

上記のように、それぞれの動物が、競技ごとに必要な『資格』(インターフェース)を実装しているわけですから、

100m走に参加する動物は、(走る)という行動がとれることが保障されています。
同じように、水泳や飛行競技に参加する動物も、(泳ぐ)、(飛ぶ)という行動が取れます。

ですので、オリンピック運営側は、参加動物に対して、(走れ)と号令をかけるだけで、100m走の競技を開始することができるわけです。

以上、自分の少ない知識を総動員させて、書いてみましたがいかがでしょうか?

きっと、インターフェースにはもっと高尚な効能がたくさんあるはずなのですが(正直、私のレベルではわかりませんw)、取り掛かりとしては、こんな感じがイメージしやすいように思います。

以前は、コードを重複させないよう、クラスの汎化にこだわりたくなってました。が、現実、設計に時間がかかりすぎることが多かったです(笑)そして、汎化した意味があまりなかった・・・なんてことも(笑)

クラスの汎化は、コード重複を減らすため、よりは、問題領域の概念を正しく表すこと、のほうが大事ですよね。

実装が多少散らばっても、早く動くものを作りながら、リファクタリングをしつつ、見えてきたものから抽象化していく、という流れが、現実的なのかな?と考えてます。

投稿2017/03/28 14:39

Meganezaru

総合スコア715

loving, alinqo👍を押しています

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

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

2

小規模の開発であればインターフェースを実装するメリットはあまりありません。
インターフェースを利用するメリットはメンテナンス性の向上だと思います。

インターフェースは実装されるクラスによって実装方法は異なりますが、インターフェースを実装されたクラスではそのメソッドを見れば何の目的のメソッドなのかわかります。

インターフェース:泳ぐ
インターフェース:飛ぶ
インターフェース:走る

基底クラス:動物(食べる、寝る、遊ぶ)

子クラス1:哺乳類

孫クラス:ジャガー←インターフェース:泳ぐ、走る

基底クラス:動物

子クラス2:カラス←インターフェース:飛ぶ

投稿2017/03/28 07:55

php5

総合スコア20

Meganezaru, i50👍を押しています

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

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

2

実例で行きましょう。

Readableインターフェイスは、readメソッドを持つインターフェイスです。

これを継承するクラスは下記のものがあります。
BufferedReader, CharArrayReader, CharBuffer, FileReader, FilterReader, InputStreamReader, LineNumberReader, PipedReader, PushbackReader, Reader, StringReader

文字列を取得して処理するメソッドの引数には、Readableインターフェイスを指定すれば、上記のいずれのクラスであろうと、一つのメソッドで動作が可能です。

もし設計を頑張ってReadableクラスとしてすべての継承元のクラスを取り込んだ巨大なクラスを作ったとしたら、おそらくメンテが効かず、入力の形式が増えたときの対応は難しくなるでしょう。

また、StringReaderクラスにはCloseableインターフェイスがありますが、CharBufferクラスにはありません。

このような複雑な違いを吸収する設計を事前に行うには、相当の思慮とコーディングが必要になります。

もちろんインターフェイス設計を間違うと継承先のすべてのクラスに影響しますので注意が必要ですが、影響範囲を狭くすることで、設計の問題を少なくすることが出来ます。

投稿2017/03/25 13:33

iwamoto_takaaki

総合スコア2883

iakio, maisumakun👍を押しています

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

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

2

わかりやすい例を挙げるなら、HTMLのDOMノードもよい例だと思います。

<DIV> <P> <BR> </DIV> <DIV> <A></A> </DIV>

HTMLの内部を調べる方法の一つにこれらのタグの階層をDOMとして表現し、そのノードを辿るということはよく行われます。DOMではDIV,P,BR,AなどのHTMLタグは全てElementというDOMノードで表現されます。その一つ下の階層を辿るにはElementインターフェースのchildというメソッドで辿れることになっています。(メソッド名などはクラスライブラリーによって違うかもしれませんがそのあたりは気にしないでください)

さて、Elementという共通のインターフェースがなかったとしたら・・・

DIV.getChildOfDiv
P.getChildOfP
A.getChildOfA
...
etc.

こういう似たようなことをするgetChildOfナンチャラメソッドを沢山用意し、今見ているノードの種類ごとに「一つ下の階層を調べる」コードを書くのに以下のような似たコードを大量生産しなければなりません。

switch (typeof(currentNode)) { case DIV: return ((DIV)current).getChildOfDiv; case P : return ((P)current).getChildOfP; case A : return ((A)current).getChildOfA; ... }

そんなことをするよりこれらの全てのノードはElementという共通のインターフェースを持つと定義して

currentNode.getChild

の1行で済ませてしまうことの方が優れた設計にできる・・・

こういったことがインターフェースの意義です。

投稿2017/03/25 12:39

KSwordOfHaste

総合スコア18392

ozwk, i50👍を押しています

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

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

2

こんにちは。

らしいですが、そんなことして何のメリットがあるんですか?開発が短縮されるんですか?

開発期間の短縮効果は確実にあると思います。

Javaはあまり知りませんが、例えばC#は列挙できるクラスはIEnumerable<T>インタフェースを継承しています。多くはコンテナですね。
ある日、IEnumerable<T>を継承したコンテナを使って列挙処理を書いたとします。その人はそのためにIEnumerable<T>の使い方を学んだことでしょう。
その日以降、その人はIEnumerable<T>を継承したコンテナ全ての列挙処理を書けるようになります。
特に新人さんにとってはかなり有り難い話と思います。

また、クラスの外部インタフェースをドキュメントだけで記述するより、インタフェースを定義することで厳密に記述でき、かつ、強制も容易なため、再利用性の改善や結合テスト時の不具合削減効果もあると思います。

投稿2017/03/25 12:32

Chironian

総合スコア23272

maisumakun, KSwordOfHaste👍を押しています

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

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

2

最初からきちんと完璧に設計すれば早い

これは理想論です。実際はなかなかその通りにはいきません。契約や設計初期における技術実働部門の発言権は大きくない場合が大半です。逆に、汎用的なユーティリティを作成する段階では、アプリケート側の都合を考慮しきれない場合もあります。

たとえば、ArrayListとLinkedListはどちらも可変長リストを実現しますが、向き不向きがあります。要素の追加削除が多いならばLinkedListの方が向いていますが、ランダムアクセスをするならばArrayListの方が向いています。このようば場合、プログラミングの段階においてはどちらにすれば良いのか確定しないことは多々ありえます。このような場合はインタフェースを使っておくと便利です。

投稿2017/03/25 11:28

編集2017/03/25 11:34
HogeAnimalLover

総合スコア4830

i50, KSwordOfHaste👍を押しています

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

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

1

自分も初学のころは同じく、不思議でしたが、
デザインパターンを学べば、インターフェースの
必要性が見えてくるかもしれません。

古い本ですが、「Head Firstデザインパターン」を読んで、
ものすごく感心しました。
オススメです。

投稿2019/02/16 23:13

uekky

総合スコア22

loving👍を押しています

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

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

1

最初からきちんと完璧に設計すれば早いと思うのですがどうでしょうか

まさに書いているじゃないですか?
しっかりと設計をする。
設計をしっかり守らせる。
守らせる為の制約手段ですよ。
多人数になると制約が必要になってくるものです。
メソッドのスペルミスなどもコードチェックの段階で回避できます。

投稿2017/03/28 04:46

編集2017/03/28 04:49
youcova

総合スコア20

KatsuMitsu👍を押しています

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

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

0

すでに接点としての回答が出揃っているので、別の観点での補足みたいな感じです。

javaで解説すると、インターフェースは質問者がおっしゃっている、「設計」です。
設計をきちんとするということは、インターフェースをきちんと作るということです。

インターフェースはインプリメンツしますが、インプリメンツには、
条例を施行する、規約を実施する、という意味があります。
クラスは実装ですから、インターフェースは設計、となります。

なので、設計がブレれば、実装もブレます。
完璧に設計できれば、実装も完璧かと思います。

オブジェクト指向言語は、
言語としての機能としてこれらを備えている、というところでしょうか。

投稿2017/03/28 23:59

編集2017/03/29 00:22
YSMS

総合スコア24

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

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

0

疎結合 というのが的確な答えなんですが、プログラムの
規模が大きくなると、インターフェースによる疎結合は
不可欠なものです。プログラムがモノリシックで複雑な化物に
なることを防ぐ有用な武器です。

オブジェクト指向である程度規模の大きなプログラムを組むにあたって
必要とされる基本原則の一つに、
IOC(Inversion of Control)
があります。多くのオブジェクト指向設計の本で詳細な
具体例が解説されていますで、それらを読むことをおすすめします。

投稿2017/03/28 14:40

tknakamuri

総合スコア56

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

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

0

上位層に変更がなく、機能を変更するために必要です。関数でなく、クラスとして機能を定義するものです。インターフェースで、下位層の機能を定義できれば、上位、下位が同時並行に開発可能になります。

投稿2017/03/28 03:46

suna9123

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.54%

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

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

質問する

同じタグがついた質問を見る

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

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