オブジェクト指向を勉強・練習している者です。エンジニアとは関係ないような質問をしてすいませんが、
インターフェースとは、
定数 | メソッド名 |
---|
↑これのみを定義(記述)しておくことで、
1.処理内容をすぐに追加・変更することができる。
2.探して書き換える手間が省ける。
3.後々変更・追加が予想される場合には便利
と、変更・追加が容易(簡単)になりますが、そこで疑問があるのですが、
インターフェースが、実装されてない
- クラス
- メソッド
これらのものは、想定されてなかったものでも突然になって変更・拡張することが可能なんでしょうか?
つまり、将来想定されてなかったもの(インターフェースが全くついていないもの)でも拡張・変更は可能なのか?ということです。
例えると、拡張を前提としていない、1つの部屋があるコンクリートの建物があったとします。
(つまり、インターフェースがついていない、確定されているメソッドやクラス)
その10年後になって、手狭になったので、そのコンクリート製の建物の構造を拡張して、2つの部屋に改装する。
(つまり、インターフェースがついてない、確定されているメソッドやクラスを元にメソッド等を拡張する。)
その拡張を前提としていない構造物(インターフェースがついてない、確定されているメソッドやクラス)を10年後になって突然変更はできるんでしょうかということです。
回答のほうお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
まずインターフェースの役割についての誤解があるようです。
インターフェースを実装されたクラスは、インターフェースで定義された関数の実装を持つことを約束する
というのが本来の意味になります。
どういうことかというと、例えば乗り物は、「走る」や「止まる」という機能を持ちます。
このことが約束されていれば走り方(ガソリンエンジンで走るや、電気で走る、またはペダルをこぐ)はどのようにしてもよいわけです。
このメソッドの外側から見れば、どうやってやるかは知らなくてもこの乗り物は「走る」ことは約束されているので、実装を知らなくても使用することができます。
ただ、インタフェースにより乗り物は 必ず走るという機能を持つ必要があります。 これが約束になります。
また、関数の実装者から見るとインタフェースで規定されていることにより、新しい乗り物を作るときに必ような機能が明確になるので何を実装するのかがわかります。
質問にある、現在想定されていないものに対して将来機能が必要になった場合ですが
インタフェースを使用するクラスについては、インタフェース側で必要になった機能の定義を増やすことでそれを使用しているクラスすべてに対し拡張された関数の実装が必須となりコンパイルエラーとなります。このため機能の実装漏れができないことを開発者に教えてくれます。
では、インタフェースのないクラスに対して拡張ができないのかというとそんなことはなく自由に拡張ができます。
また、インタフェースがついているクラスについてもインタフェースで定義された関数以外の関数の実装もできます。
【参考】上記拙い説明なので下記サイトを紹介して補足とします。
投稿2018/06/13 16:40
総合スコア2404
0
ベストアンサー
もう少し mr0237さんの提示された部屋の例えでまとめてみます。
部屋というクラスだと自立した動作がないので若干説明に苦しいところもありますがご容赦ください。
以下のようなイメージで説明します。
- 「インターフェース」= 「機能要件、建築に関する法令」
- 「クラス」=「設計図」
- 「インスタンス」= 「建築された部屋」
インタフェースを使わない部屋の変更
mr0237さんは部屋が欲しくなったので部屋の 設計図を作成 しました。
** これはJavaでいうと下記のクラスを定義するということです **
Java
1// 部屋の設計図 2class Room { 3 // 部屋の広さを返す関数 4 double getSize() { 5 return 6; // 6畳 6 } 7}
この設計図に従って 部屋の建築 を行いました。
** これはJavaでいうとクラスからインスタンスを作成するということです **
Java
1// 6畳の部屋を作成する 2Room myRoom = new Room();
このクラス Roomはインタフェースを基にしてはいません。
この部屋にテレビを置く(拡張する)ためには以下のように クラスの設計を変更 します。
Java
1// 部屋の設計図 2class Room { 3 // 部屋の広さを返す関数 4 double getSize() { 5 return 6; // 6畳 6 } 7 // テレビを持っている 8 boolean hasTelevision() { 9 return true; 10 } 11}
この部屋の広さを6畳から8畳に (変更する) ためには既存 メソッドの実装を変更 します。
Java
1// 部屋の設計図 2class Room { 3 // 部屋の広さを返す関数 4 double getSize() { 5 return 8; // 8畳 6 } 7}
上記は、当初 想定されてなかったものでも突然になって変更・拡張する という目的にかなうもので
前のコメントはこのやり方のことを言っています。
「インターフェースが、実装されてないクラスやメソッドでは、突然になって変更・拡張することが可能なのか?」に対しては、
「可能です」という回答になります。
つまりクラスの設計を行う人が何を変更するかがわかっているのであればインタフェースがなくても変更も拡張もしてもよいのです。
インタフェースを使う場合
部屋を作るうえでは、建築基準法や消防法といった法律があります。これをイメージしてほしいのですが下記のようになります。
Java
1interface 建築基準法 { 2 // 窓があること 3 boolean has窓(); 4} 5 6// この部屋の設計図は建築基準法にのっとったものです 7class Room implements 建築基準法{ 8 // 部屋の広さを返す関数 9 double getSize() { 10 return 3.3*6; // 約6畳 11 } 12 @Overide 13 boolean has窓() { 14 return true; 15 } 16}
1年後法令が変更になって消防法を満たす必要が出てきました。
java
1interface 建築基準法 { 2 // 窓があること 3 boolean has窓(); 4} 5interface 消防法 { 6 // 消火器の設置が義務付けられている 7 boolean has消火器(); 8} 9class Room implements 消防法, 建築基準法{ 10 // 部屋の広さを返す関数 11 double getSize() { 12 return 3.3*6; // 約6畳 13 } 14 @Overide 15 boolean has窓() { 16 return true; 17 } 18}
このとき上記のままですと法令に不適合(コンパイルエラー)になります。
適合させるためには、以下のように設計を変更して法令(インターフェース)で決められたメソッドを実装する必要があります。
java
1class Room implements 消防法, 建築基準法{ 2 // 部屋の広さを返す関数 3 double getSize() { 4 return 3.3*6; // 約6畳 5 } 6 @Overide 7 boolean has窓() { 8 return true; 9 } 10 @Overide 11 boolean has消火器() { 12 return true; 13 } 14}
また暫くして消防法が変更になり火災報知機の設置が義務付けられました。
** これはJavaでいうとインタフェースにメソッド定義を追加するということです **
Java
1interface 消防法 { 2 // 消火器の設置が義務付けられている 3 boolean has消火器(); 4 // 火災報知機の設置が義務付けられている 5 boolean has火災報知機(); 6}
このときもクラスRoomは不適合(コンパイルエラー)になりますので適合させるために部屋の設計を変更します。
Java
1class Room implements 消防法, 建築基準法{ 2 // 部屋の広さを返す関数 3 double getSize() { 4 return 3.3*6; // 約6畳 5 } 6 @Overide 7 boolean has窓() { 8 return true; 9 } 10 @Overide 11 boolean has消火器() { 12 return true; 13 } 14 @Overide 15 boolean has火災報知機() { 16 return true; 17 } 18}
このように法令(インタフェース)に沿った設計(クラス)の部屋ですが、設計者がベランダを追加したいと思った場合はインタフェースに追加しなくても設計(クラス)に追加することが可能です。
(ベランダがなければならないという法令はないので...)
Java
1class Room implements 消防法, 建築基準法{ 2 // 部屋の広さを返す関数 3 double getSize() { 4 return 3.3*6; // 約6畳 5 } 6 boolean hasベランダ() { 7 return true; 8 } 9 @Overide 10 boolean has窓() { 11 return true; 12 } 13 @Overide 14 boolean has消火器() { 15 return true; 16 } 17 @Overide 18 boolean has火災報知機() { 19 return true; 20 } 21}
どうでしょうか?伝わりますでしょうか?
コメントへの回答
それは上記の例(コンクリート製の建物の構造)に例えると、「インターフェース」とは拡張を前提として建築するものであり、「拡張を前提とされていない」建物を建設することが不可能ということでしょうか?
今回私は「拡張」という意味を「継承」とは違うものとして理解して説明をしています。
「拡張を前提とする、しない」ということを気にしておられるようですね、私の知る限り 拡張、変更できないクラスというのは言語仕様(Javaでの話をしてしまいますが)としては存在しないと思います。すべてのクラスは拡張も変更もできます。(クラス定義を変更するだけなので)
言い換えると
「インターフェース」とは設計に一定の基準を定めるものであり、「要件を満たさない」設計をすることができないよう使用されるもの
となります。
質問の内容を改めて見直してみると
インターフェースとは、
- 処理内容をすぐに追加・変更することができる。
- 探して書き換える手間が省ける。
- 後々変更・追加が予想される場合には便利
ここで書かれている内容においては インタフェースというより継承によるメリットを表しているように思われます。
投稿2018/06/18 02:31
編集2018/06/20 08:54総合スコア2404
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/17 10:24
2018/06/17 14:11 編集
2018/06/17 17:45