クラス

Dim val As ComplexTest

Private Type ComplexTest
real As Variant
imag As Variant
End Type

Private Sub Class_Initialize()
val.real = 0
val.imag = 0
End Sub

Public Sub setter(r, i)
val.real = r
val.imag = l
End Sub

Public Property Get real() As Variant
real = val.real
End Property
Public Property Get imag() As Variant
imag = val.imag
End Property
Public Property Set real(a As Variant)
val.real = a
End Property
Public Property Set imag(a As Variant)
val.imag = a
End Property
クラスと言っても実はたいしたことはできない。
オブジェクトと言いながらも、実際にできるのは構造体+付属のプロシージャといった程度だ。
オブジェクト指向プログラミングなどとは程遠い感じだ。
だからオブジェクトとは言わずにクラスモジュールと称しているのだろう。

まあ、それはそれとしてプログラムのカプセリングにちょびっとでも貢献するかもしれないので押さえておこう。
まずこのプログラムは「クラスモジュール」として記述する。
挿入→クラスモジュールで箱を作る。
オブジェクト名のところがクラス名になるのでComplexTestと設定する。

まず1行目がこのクラスの持つ内部変数である。
外からは見えない。
次にこのクラス(オブジェクト)のプロパティを定義する。
3行目〜6行目だ。
しかしこれも外からは見えない。

さてこれを使うプログラムはどうなるのか。
Dim obj_a As ComplexTest
Set obj_a = New ComplexText
とこんな感じでオブジェクトを作成する。
オブジェクトのプロパティを操作するには次のようにするだろう。
a = obj_a.real
これが実行された時に対応する記述が17行目〜19行目になる。
obj_a.real = a
これに対しては23行目〜25行目が対応する。

さて、オブジェクトを作るとそれを使って演算したくなるものだ。
例えば同様に2つオブジェクトを追加して c_obj = a_obj + b_obj みたいな感じだ。
しかしそれは叶わない。
オブジェクト指向言語には用意されているべき演算子のオーバーロードがないからだ。
それ以前に“継承”すらないのだから話にならない。

それなら関数でできないものかと思うのが筋なのだが例えば
Public Function add(a As ComplexTest, b As ComplexTest) As ComplexTest
Dim c As Variant
c.real = a.real + b.real
c.imag = a.imag + b.imag
innner = a.real * b.real + a.imag * b.imag
End Function
こんな風に書いても無駄である。
クラス名を返値とする関数は定義できないとエラーになる。

じゃあ、せめてスカラー値を返す関数はつくれないのか、と
Public Function inner(a As ComplexTest, b As ComplexTest) As Variant
Dim c As Variant
c.real = a.real + b.real
c.imag = a.imag + b.imag
innner = a.real * b.real + a.imag * b.imag
End Function
こんな風に書いてもクラス名を引数にすることすら駄目だとエラーとなる。

じゃあなにができるんだといえば、どうやらスカラー値を返すか、ただの手続きだけ。
引数もスカラー値で内部変数をいじくることしかできないようだ。
その操作によって変わる状態をプロパティを使って引き出したり、状態を設定したりができるだけのようである。

要はクラスと言っても「オブジェクト指向ができる!」というのは早とちりということだ。

もともと構造体がないので、構造体として使えば良いのかもしれない。
comments (0)

コメント

Comment Form