PROPERTY は、正常な監視任務、あるいはメンバー・アクセスによって、オブジェクトの値を設定したり検索する方法を提供するだけでなく、オブジェクト自体を更新する必要がある場合、オブジェクトにアクションを行なわせます。
PROPERTY は、
メンバー手続き と同様に宣言します。ただ、予約語
Sub や
Function の代わりに、
Property を使う点だけが異なります。
例えば、ウィンドウ・システムや、GUI ライブラリのために、ウィンドウ・クラスを考慮します。
Type Window
Private:
As String title_
End Type
Dim As Window w
ウインドウのタイトルを設定するために、
setter property を加えることができます:
Type Window
Declare Property title(ByRef s As String)
Private:
As String title_
End Type
Property Window.title(ByRef s As String)
This.title_ = s
End Property
Dim As Window w
w.title = "My Window"
Property はメンバー
Sub に、よく似ています。パラメーターをとり、オブジェクトをパラメーターに基づき新しい状態に更新するからです。
しかし、このパラメーターを送るための構文は、基礎的な割り当てです。関数呼出しではありません。
title Property に新しい値を割り当てることによって、Property 手続きは、与えられた新しい値で自動的に呼ばれます。そして、変更を反映するために、ウィンドウを更新することができます。
内部に、どのように Property 状態を表わすかは、オブジェクトしだいです。
設計上、Property は、一度に1つの値しか割り当てることができません。また、その結果、Property 手続きは、複数のパラメーターを持つことができません。
ウィンドウ・タイトルを設定した後に、それを検索することも可能です。
以下は、
getter Property を加える方法です:
Type Window
'' setter
Declare Property title(ByRef s As String)
'' getter
Declare Property title() As String
Private:
As String title_
End Type
'' setter
Property Window.title(ByRef s As String)
This.title_ = s
End Property
'' getter
Property Window.title() As String
Return This.title_
End Property
Dim As Window w
w.title = "My Window"
Print w.title
ゲッターは、
Function と、とてもよく似ています。
ゲッターは、property の現在の値を返すことが期待されます。そして、ゲッターは、必要なら、現在の値を、他の内部の値から計算します。
setter と
getter は、同じ識別子を使うことに注意して下さい。これは、これらが同じ property を取り扱うことを示しています。
ちょうど、
メンバー手続き 多重定義 のように、これらに異なるパラメータ型があるなら、複数のセッターを指定することができます:
Type Window
Declare Property title(ByRef s As String)
Declare Property title(ByVal i As Integer)
Declare Property title() As String
Private:
As String title_
End Type
Property Window.title(ByRef s As String)
This.title_ = s
End Property
Property Window.title(ByVal i As Integer)
This.title_ = "Number: " & i
End Property
Property Window.title() As String
Return This.title_
End Property
Dim As Window w
w.title = "My Window"
Print w.title
w.title = 5
Print w.title
property の上の例との比較で、以下は、property を使わない類似のコードです:
Type Window
Declare Sub set_title(ByRef s As String)
Declare Sub set_title(ByVal i As Integer)
Declare Function get_title() As String
Private:
As String title
End Type
Sub Window.set_title(ByRef s As String)
This.title = s
End Sub
Sub Window.set_title(ByVal i As Integer)
This.title = "Number: " & i
End Sub
Function Window.get_title() As String
Return This.title
End Function
Dim As Window w
w.set_title("My Window")
Print w.get_title()
w.set_title(5)
Print w.get_title()
コードは基本的に同じです。構文だけが異なります。
Property は、setter/getter 概念と、クラスのメンバー変数に、値を
代入演算 して
アクセス する、ライブラリの言語の正常な方法との結合を、特に目指しています。
これらのどちら方法を好むかを決めることは、プログラマの責任です。
テキスト・ユーザ・インタフェース・ウインドウ・クラスが、ポジションとタイトルを設定するために、property を使っていることを示す例が、ここにあります:
Namespace tui
Type Point
Dim As Integer x, y
End Type
Type char
Dim As UByte value
Dim As UByte Color
End Type
Type Window
'' public
Declare Constructor _
( _
x As Integer = 1, y As Integer = 1, _
w As Integer = 20, h As Integer = 5, _
title As ZString Ptr = 0 _
)
Declare Destructor
Declare Sub show
'' title property
Declare Property title As String
Declare Property title( new_title As String )
'' position properties
Declare Property x As Integer
Declare Property x( new_x As Integer )
Declare Property y As Integer
Declare Property y( new_y As Integer )
Private:
Declare Sub redraw
Declare Sub remove
Declare Sub drawtitle
Dim As String p_title
Dim As Point Pos
Dim As Point siz
End Type
Constructor Window _
( _
x_ As Integer, y_ As Integer, _
w_ As Integer, h_ As Integer, _
title_ As ZString Ptr _
)
Pos.x = x_
Pos.y = y_
siz.x = w_
siz.y = h_
If( title_ = 0 ) Then
title_ = @"untitled"
End If
p_title = *title_
End Constructor
Destructor Window
Color 7, 0
Cls
End Destructor
Property Window.title As String
title = p_title
End Property
Property Window.title( new_title As String )
p_title = new_title
drawtitle
End Property
Property Window.x As Integer
Return Pos.x
End Property
Property Window.x( new_x As Integer )
remove
Pos.x = new_x
redraw
End Property
Property Window.y As Integer
Property = Pos.y
End Property
Property Window.y( new_y As Integer )
remove
Pos.y = new_y
redraw
End Property
Sub Window.show
redraw
End Sub
Sub Window.drawtitle
Locate Pos.y, Pos.x
Color 15, 1
Print Space( siz.x );
Locate Pos.y, Pos.x + (siz.x \ 2) - (Len( p_title ) \ 2)
Print p_title;
End Sub
Sub Window.remove
Color 0, 0
Var sp = Space( siz.x )
For i As Integer = Pos.y To Pos.y + siz.y - 1
Locate i, Pos.x
Print sp;
Next
End Sub
Sub Window.redraw
drawtitle
Color 8, 7
Var sp = Space( siz.x )
For i As Integer = Pos.y + 1 To Pos.y + siz.y - 1
Locate i, Pos.x
Print sp;
Next
End Sub
End Namespace
Dim win As tui.window = tui.window( 3, 5, 50, 15 )
win.show
Sleep 500
win.title = "Window 1"
Sleep 250
win.x = win.x + 10
Sleep 250
win.title = "Window 2"
Sleep 250
win.y = win.y - 2
Sleep 250
Locate 25, 1
Color 7, 0
Print "Press any key...";
Sleep
ウィンドウの位置やタイトルを更新すると、ウィンドウがどのように自動的に描き直されるかに、注意してください。
Property は、
index と呼ばれる付加パラメータを持つことができます。(現在、1つの付加パラメータだけが許可されます)
index は、Property が、あたかも配列(わずか 1次元ですが)のように、Property の名前の後ろの括弧の中で、指定されます。
例えば:
Type IntArray
'' setters
Declare Property value(index As Integer, v As Integer)
Declare Property value(index As String, v As Integer)
Declare Property value(index As Integer, v As String)
Declare Property value(index As String, v As String)
'' getters
Declare Property value(index As Integer) As Integer
Declare Property value(index As String) As Integer
Private:
Dim As Integer data_(0 To 9)
End Type
Property IntArray.value(index As Integer) As Integer
Return This.data_(index)
End Property
Property IntArray.value(index As String) As Integer
Return This.data_(CInt(index))
End Property
Property IntArray.value(index As Integer, v As Integer)
This.data_(index) = v
End Property
Property IntArray.value(index As String, v As Integer)
This.data_(CInt(index)) = v
End Property
Property IntArray.value(index As Integer, v As String)
This.data_(index) = CInt(v)
End Property
Property IntArray.value(index As String, v As String)
This.data_(CInt(index)) = CInt(v)
End Property
Dim a As IntArray
a.value(0) = 1234
a.value("1") = 5678
a.value(2) = "-1234"
a.value("3") = "-5678"
Print a.value(0)
Print a.value("1")
Print a.value(2)
Print a.value("3")
Sleep
これは、整数配列をシミュレートします。文字列を割り当てることができ、さらに文字列で索引を付けることができます。
別の例については、
Property を参照してください。