属性 (Properties)
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgProperties
- 最后更新: 2021-10-30
属性是成员变量与成员过程的特殊结合体。
它们提供了一种通过普通赋值或成员访问语法来设置或获取对象值的方式,同时也允许对象在需要更新自身时执行相应操作。
基本属性 声明和使用 setter 与 getter 属性。
索引属性 带附加参数的属性。
基本属性
属性的声明方式类似于成员过程,只是使用 Property 关键字代替 Sub 或 Function。例如,考虑一个窗口系统或 GUI 库的窗口类。
start GeSHi
Type Window
Private:
As String title_
End Type
Dim As Window wend GeSHi
为了设置窗口标题,可以添加一个 setter 属性:
start GeSHi
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"end GeSHi
它非常类似于成员 Sub,它接受一个参数并根据参数将对象更新到新状态。但是,发送此参数的语法是基本赋值,而不是函数调用。通过将新值赋给 title 属性,属性过程将自动以给定的新值被调用,并可以更新窗口以反映更改。对象如何在内部表示属性状态由对象自己决定。
根据设计,属性一次只能被赋一个值,因此属性过程不能有多个参数。
设置窗口标题后,还应该能够检索它。以下是添加 getter 属性的方法:
start GeSHi
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.titleend GeSHi
getter 非常类似于 Function。它应该返回属性的当前值,并允许在需要时从其他内部值计算当前值。注意 setter 和 getter 使用相同的标识符,表明它们处理同一个属性。
就像方法重载一样,可以指定多个 setter,只要它们具有不同的参数类型:
start GeSHi
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.titleend GeSHi
与此属性示例对比,以下是不使用属性的类似代码:
start GeSHi
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()end GeSHi
代码基本相同,只是语法不同。属性专门设计为将 setter/getter 概念与语言中直接赋值和访问类成员变量的正常方式相结合。由程序员决定哪种方式更合适。
以下是一个演示文本用户界面窗口类的示例,允许使用属性设置位置和标题:
start GeSHi
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 属性
Declare Property title As String
Declare Property title( new_title As String )
'' 位置属性
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...";
Sleepend GeSHi
注意更新窗口位置或标题如何自动导致窗口重新绘制。
索引属性
属性可以有一个称为 index(索引)的附加参数(目前只允许一个附加参数)。索引在属性名后面的括号中指定,就像属性是一个数组(只有一个维度)一样。例如:
start GeSHi
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")
Sleepend GeSHi
这模拟了一个可以被赋予字符串的整数数组,甚至可以用字符串作为索引。参见 KeyPgProperty 获取另一个示例。
返回 目录