VB.netで説明するオブジェクト指向

はじめに

良い教本というのはどういうのだろう 島国大和のド畜生
より

サンプルソース
 ⇒まず動作するものを見せる。
②これはこういう考え方だ。
 ⇒理屈の説明
③なぜなら、ほら便利だろう。
 ⇒そのやり方を採用する理由

そういえばオブジェクト指向はよくわからなかったけどサンプルソースを読んだり実際に動くものを書いたりしてるうちに自然と身に付いた。

最近オブジェクト指向の解説記事を見た
http://ulog.cc/a/fromdusktildawn/16994
けどこれはイマイチわかりにくいと思う
個人的には各種インスタンスを格納してる「配列」って奴の型がわからないのが気持ち悪い。
VBを学習する際にVariant型やObject型を多用しないように叩き込まれたせいだろう。

記事の後半に

rubyの場合、単に「描く」メソッドを持っているオブジェクトを配列に格納してループを回せばそれでポリモルフィックなメソッド呼び出しが出来ますが、Javaだと配列に格納された全てのオブジェクトが「draw()」メソッドを持っていることを、ソースコード内で「保証」するような書き方をしないと、コンパイルエラーになります。(「バグがないこと」を「保証」しているわけではない)
Javaだと、「draw()」メソッドを持っていることを「保証」するやり方は二通りあります。
一つがインタフェースを使うやり方です。この例がそれで、「interface」宣言を使って「draw()」メソッドを持つ「Picture」インタフェースを定義し、各クラスが「implements Picture」という宣言をすることで、そのインタフェースを「実装」していることを明示しています。
もう一つが「継承」を使うやり方で、親クラスで「draw()」メソッドを定義し、その親クラスを各図形クラスが「継承」し、それぞれの子クラスで「draw()」メソッドの実装を上書きすることで、同様のことができます。

このように、Java言語だと「インタフェース」もしくは「継承」を使わないとポリモルフィズムが実装できませんので、それらがポリモルフィズムと一体不可分であるかのように錯覚してしまう方がときどきいらっしゃいますが、「インタフェース」も「継承」も使わずにポリモルフィズムを使ったクラス設計の出来るrubyのような言語を見て分かるとおり、それらはポリモルフィズムの本質とは直接関係があるわけではありません。

とあるように「インタフェース」や「継承」がおまけみたいに書かれてるけど、オブジェクト指向の学習には最低限「継承」の説明が必要だろう。

例題

・このフォーム上のすべてのコントロールのテキストを変更したい

普通にやると

Dim strTmp As String = "Hello object-oriented"
TextBox1.Text = strTmp
TextBox2.Text = strTmp
・・・・・・・・・・

と画面上のコントロール全てを羅列する必要があり、あとからコントロールの追加・変更があるとそのたびに修正する必要がある。

継承

VBで画面上に配置できるテキストボックスやグループボックスのコントロールは(フォームですら)、Controlクラスを継承してるのでTextプロパティを含む色々なプロパティが共通で使える。

Controlクラスで定義されたプロパティは、Controlクラスを継承して作られた全てのクラスで使えるのです。

オブジェクト指向的な回答

フォーム上のコントロールを親クラスのControlクラスとして扱うことで一挙にプロパティの変更が可能です。

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call sChangeProperty(Me)
End Sub

Private Sub sChangeProperty(ByVal c As Control)
c.Text = "Hello object-oriented"

'コントロールがコンテナの時、各子コントロールについて再帰処理
For Each x As Control In c.Controls
Call sChangeProperty(x)
Next
End Sub
End Class

再帰処理についてはここでは説明しないので各自調べてください

実行すると(ボタンを押すと)こうなります。

ね、簡単でしょ?

例題のTextプロパティだとイマイチ恩恵がわかりにくいですが、フォントを変えたり色を変えたり色々実用的な使い方の可能性は無限大です。

Call sEnable(Me)

の所を

Call sEnable(Me.GroupBox1)

にすれば影響範囲を変えることも出来ます。

おわりに

rubyでもJavaでもCでもなくてVB.netなのが申し訳ないですが・・・

ここで説明したのは最低限の実用例なので、これが理解できたらまた冒頭のオブジェクト指向の解説記事に戻ってみてください。