回答編集履歴
2
途中の説明を更新
answer
CHANGED
@@ -59,7 +59,8 @@
|
|
59
59
|
そこでインタフェースの出番です。(正確には多態性の出番とするべきでしょうか。インタフェースは多態性を実現するひとつに手段に過ぎません)
|
60
60
|
|
61
61
|
言語がインタフェースを持っていて、すべての**複数行の文字列を内部に格納するGUI**がMultiLineというインタフェースの実装になっていると想像してください。
|
62
|
-
|
62
|
+
インタフェースMultiLineには、`len`、`get`、`add`、`clear`などが定義されるはずです。
|
63
|
+
そうであれば、
|
63
64
|
```
|
64
65
|
procedure copyMultiLine(a: MultiLine, b: MultiLine)
|
65
66
|
i: int
|
@@ -72,17 +73,21 @@
|
|
72
73
|
```
|
73
74
|
というひとつの手続きだけがあればすべて事足ります。
|
74
75
|
|
75
|
-
ListBox`a`からListBox`b`にコピーしたいなら`copyMultiLine(a, b)`
|
76
|
+
ListBox`a`からListBox`b`にコピーしたいなら`copyMultiLine(a, b)`と呼べばいいし、
|
76
|
-
TextEdit`c`からListBox`d`にコピーしたいなら`copyMultiLine(c, d)`
|
77
|
+
TextEdit`c`からListBox`d`にコピーしたいなら`copyMultiLine(c, d)`と呼べばいいわけです。
|
78
|
+
copyLinesTextEditとcopyLinesListBoxが別になっている必要はないのです。
|
77
79
|
|
78
|
-
|
80
|
+
インタフェース(やクラス継承)の何が便利なのかわからない、という人の多くは、このような多態を利用した処理の書き方を知らないか、慣れていないように見受けられます。
|
79
|
-
|
81
|
+
TextEditやListBoxのような**具象**を引数に受け取る手続きは想像するのが容易です。しかしインタフェースのような**抽象**を引数に受け取る手続きが書ける、という想像がしにくいのでしょう。
|
80
82
|
|
81
|
-
そ
|
83
|
+
抽象を引数に受け取る手続きには、それを具象化したものなら**なんでも**渡せます。
|
82
|
-
copyMultiLine
|
84
|
+
copyMultiLineにListBoxもTextEditもどちらも渡せるように。
|
83
|
-
|
85
|
+
インタフェースMultiLineの具象であるなら、インタフェースMultiLineで定義されている要素は**すべて実装されている**という保証があるからです。
|
84
86
|
|
87
|
+
インタフェースMultiLineを受け取るような手続きの中では、インタフェースMultiLineで定義されている要素だけしか使えません。しかしインタフェースMultiLineで定義されている要素だけで**意味がある一連の手続き**が書けていますよね。
|
85
88
|
|
89
|
+
そうできるようにインタフェースは定義されるべきです。
|
90
|
+
|
86
91
|
----
|
87
92
|
|
88
93
|
考える順番に気をつけてください。
|
@@ -98,7 +103,7 @@
|
|
98
103
|
|
99
104
|
同じ概念を内包するコンポーネントなら、違う手続きで操作するのはよくないです。
|
100
105
|
同じ手続きなら、違う名前をつけるのはよくないです。
|
101
|
-
(逆から言うと違う名前の方が相応しいなら、たまたま似ているだけの「別の概念」
|
106
|
+
(逆から言うと違う名前の方が相応しいなら、たまたま似ているだけの「別の概念」だと分析するべきです)
|
102
107
|
それはつまり、言語にインタフェースが存在しようがしまいが、ルールはある方がいいってことです。
|
103
108
|
|
104
109
|
言語要素としてのインタフェースは、そういったルールを宣言する、あるいは明確にするのに役立ちます。また、ルールが遵守されていることを保証してくれます。
|
1
「ルールを強制させる」ことについての追記
answer
CHANGED
@@ -56,7 +56,7 @@
|
|
56
56
|
|
57
57
|
----
|
58
58
|
|
59
|
-
そこでインタフェースの出番です。(正確には
|
59
|
+
そこでインタフェースの出番です。(正確には多態性の出番とするべきでしょうか。インタフェースは多態性を実現するひとつに手段に過ぎません)
|
60
60
|
|
61
61
|
言語がインタフェースを持っていて、すべての**複数行の文字列を内部に格納するGUI**がMultiLineというインタフェースの実装になっていると想像してください。
|
62
62
|
|
@@ -75,11 +75,8 @@
|
|
75
75
|
ListBox`a`からListBox`b`にコピーしたいなら`copyMultiLine(a, b)`でいいし、
|
76
76
|
TextEdit`c`からListBox`d`にコピーしたいなら`copyMultiLine(c, d)`でいいわけです。
|
77
77
|
|
78
|
-
なぜこれで済むのか?
|
79
|
-
|
80
78
|
複数行の文字列を内部に格納するGUIは、このような**操作を持っているはずだ**と想定できるなら、それをインタフェースとして定義します。
|
81
79
|
そして、複数行の文字列を内部に格納するGUIコンポーネントは、そのインタフェースを実装すればいい。
|
82
|
-
それが「ルールを強制させる」の意味です。
|
83
80
|
|
84
81
|
そうなっていれば、あるインタフェースを持つ**もの**は、そこに定義してある機能を間違いなく**使える**と保証されるのです。
|
85
82
|
copyMultiLineのように、その機能だけに着目したプログラムが、書けるようになります。
|
@@ -88,6 +85,21 @@
|
|
88
85
|
|
89
86
|
----
|
90
87
|
|
91
|
-
順番に気をつけてください。
|
88
|
+
考える順番に気をつけてください。
|
92
89
|
「ある概念を内包する部品」を設計する時、それらは「このような操作を持っているはずだ」という発想が先です。
|
93
|
-
それをルールとして定義するものがインタフェースです。
|
90
|
+
それをルールとして定義するものがインタフェースです。
|
91
|
+
|
92
|
+
GUIを構築するためのプログラムを考えます。
|
93
|
+
リストボックスとか、プルダウンリスト、コンボボックスを操作する手続きを考えていると、これらは(文字列の取得とか追加とか件数の取得とか初期化とかの)同じような操作が必要なことに気づきます。
|
94
|
+
それはなぜかというと「順序がある複数の文字列を内部に持つ」という構造が同じだからです。
|
95
|
+
そう考えると用途は違っても、テキストボックスも同様な構造を持つことがわかります。
|
96
|
+
|
97
|
+
たとえ言語にインタフェースが**存在しなかった**としても、リストボックスは`get(int)`で、プルダウンリストは`item(int)`で、テキストエディットは`line(int)`で文字列を取得するようなら、とても変じゃありませんか?
|
98
|
+
|
99
|
+
同じ概念を内包するコンポーネントなら、違う手続きで操作するのはよくないです。
|
100
|
+
同じ手続きなら、違う名前をつけるのはよくないです。
|
101
|
+
(逆から言うと違う名前の方が相応しいなら、たまたま似ているだけの「別の概念」を取り扱っていると分析するべきです)
|
102
|
+
それはつまり、言語にインタフェースが存在しようがしまいが、ルールはある方がいいってことです。
|
103
|
+
|
104
|
+
言語要素としてのインタフェースは、そういったルールを宣言する、あるいは明確にするのに役立ちます。また、ルールが遵守されていることを保証してくれます。
|
105
|
+
それが「ルールを強制させる」の意味もしくはメリットです。
|