FreeBASIC マニュアルのトップに戻る

FreeBASIC 多様性をシミュレート

目次→教本→いっしょに学ぼうSimulating Polymorphism←オリジナル・サイト

多様性をシミュレート 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

序論

多様性は、オブジェクト指向プログラムの強力なツールです。
多形メソッド(Sub か Function)は、オブジェクトの定義に応じて、動作が異なります。
たとえば、動物のオブジェクトには、犬には吠え声、猫には猫の鳴き声を発する、話し方があります。
FreeBASIC は以前は真の多型をサポートしていませんでした。
しかし、メソッド・ポインタを使うと、多相メソッドをシミュレートすることができます。

FreeBasic 0.90.0 以降 は、多様性を正式サポートしました。

多様性

多形のメソッドは、同じ型とパラメータ・リストを持つ、サブルーチンか関数です。しかし、異なるオブジェクトに縛られると、異なる振る舞いをします。
動物オブジェクトには、犬のための鳴き声と、猫のための鳴き声を発する、発声メソッドがあります。
FreeBasic には、まだクラスがないので、本当の多形のメソッドを実装することはできません。しかし、メソッド・ポインタを使って、振舞いをシミュレートできます。

下のリストは、一対の、定義と、拡張型の宣言を、示しています:
#define isdog 1
#define iscat 2

Type animal
    Public:
    speak As Sub ()
    Declare Constructor (anid As Integer)
End Type


#defines は、生成されるオブジェクトの型を伝えるために、Constructor に渡されます。
speak As Sub() 定義は、メソッド・ポインタを定義します。
見てお分かりでしょうが、2つの別のサブルーチンのアドレスは、発声方法ポインタに渡されます。
以下のリストは、異なる発声サブルーチンと、Constructor メソッドを示します:

'犬オブジェクトの、鳴き方
Sub Bark ()
    Print "ワンワン!"
End Sub

'猫オブジェクトの鳴き方
Sub Meow ()
    Print "ニャーオ!"
End Sub

'動物 ID に基づく、適切な鳴き方ポインタを設定します
Constructor animal (anid As Integer)
    If anid = isdog Then
        This.speak = @Bark
    ElseIf anid = iscat Then
        This.speak = @Meow
    End If
End Constructor


Bark サブルーチンは、オブジェクトが犬ならば呼ばれます。そして、Meow サブルーチンは、オブジェクトが猫ならば呼ばれます。
あなたは、メソッドをなぜ多重定義できないか、不思議に思うでしょう。
多重定義のメソッドに対して、型とパラメータ・リストはユニークでなければなりません。多形のメソッドでは、型とパラメータ・リストは、同じでなければなりません。
Bark と Meow は、同じパラメータ・リストを持っています。これは、パラメタではないので、メソッドを多重定義ることができません。

Constructor コードは、プログラムが、使うために呼ぶメソッドを決めるところです。
anid が isdog と等しいなら、発声メソッド・ポインタは、Bark サブルーチンのアドレスに設定されます。
anid が iscat と等しいなら、発声は、Meow サブルーチンのアドレスに設定されます。
addressof 演算子 @ は、Bark と Meow のアドレスを、発声ポインタに渡すため使われます。

this オブジェクト参照は、隠されたパラメタで、型に参照をつける Constructor に渡されます。この場合の型は、動物です。
あなたは、これを、型の中で内部変数を参照するために使用できます。

やるべく残っている唯一のことは、オブジェクトを作成して、初期化することです:

'犬と猫のオブジェクトを作成します
Dim myDog As animal = isdog
Dim mycat As animal = iscat


ここで、myDog と myCat は、適切なフラグが Constructor に渡されている状態で、作成されます。それで、適切な参照が、設定されます。
オブジェクトがいったん作成されると、あなたは、それぞれのオブジェクトの発声メソッドを呼ぶことができます。

'動物に鳴かせましょう
Print "犬が鳴きます:";
myDog.speak ()
Print "猫が鳴きます:";
myCat.speak ()


あなたは、同じ発生メソッドを呼んでいます、しかし、出力は異なっています:

犬が鳴きます:ワンワン!
猫が鳴きます:ニャーオ!


これは多形メソッドの本質です。

下は、これまで記述したことを合わせた、完全なプログラムです:

'メソッド・ポインタを使って、多様性をシミュレート
'Richard D. Clark (リチャード・D.クラーク)
'FreeBasic の CVS(Concurrent Versions System) バージョンを使います
'**********************************************

#define isdog 1
#define iscat 2

Type animal
    Public:
    speak As Sub ()
    Declare Constructor (anid As Integer)
End Type

'犬オブジェクトのための鳴き方
Sub Bark ()
    Print "ワンワン!"
End Sub

'猫オブジェクトのための鳴き方
Sub Meow ()
    Print "ニャーオ!"
End Sub

'動物 ID に基づく適切な鳴き方ポインタを設定します
Constructor animal (anid As Integer)
    If anid = isdog Then
        This.speak = @Bark
    ElseIf anid = iscat Then
        This.speak = @Meow
    End If
End Constructor

'犬と猫オブジェクトを作成します
Dim myDog As animal = isdog
Dim mycat As animal = iscat

'動物に鳴かせます
Print "犬が鳴きます:";
myDog.speak ()
Print "猫が鳴きます:";
myCat.speak ()

Sleep
End


継承と仮想性による「多様性」がサポートされました (fbc 0.90.0 〜)

上の例を、fbc バージョン 0.90.0 以降用に書き換えました。
抽象/仮想のメソッドの継承(サポートされている機能)によって、多様性を使います:

'FreeBasic バージョン >= 0.90.0

'基底型 animal
Type animal Extends Object
    Declare Abstract Sub speak ()
End Type

'派生型 dog
Type dog Extends animal
    Declare Virtual Sub speak () Override
End Type

'dog object の発声方法
Virtual Sub dog.speak ()
    Print "ワンワン!"
End Sub

'派生型 cat
Type cat Extends animal
    Declare Virtual Sub speak () Override
End Type

'cat object の発声方法
Virtual Sub cat.speak ()
    Print "ニャーオ!"
End Sub

'動的オブジェクトとして犬と猫を、動物ポインタを通して作成します
Dim myDog As animal Ptr = New dog
Dim mycat As animal Ptr = New cat

'動物の鳴き声を取得します
Print "犬が鳴く ";
myDog->speak()
Print "猫が鳴く ";
myCat->speak()

Sleep

'動的オブジェクトを削除
Delete myDog
Delete myCat


いっしょに学ぼう に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2019-02-26 09:18:46
日本語翻訳:WATANABE Makoto、原文著作者:WikiRick(Rick Clark aka rdc)

ホームページのトップに戻る

表示-非営利-継承