VB.net入门(10):补充:类~属性

发表于:2007-06-30来源:作者:点击数: 标签:
刚刚发现类还没有写完,还有一个比较大的部分:属性(Property)。 Property在 Java 和C++里面都是闻所未闻的。通常认为类当中只要有成员和方法就行了。至于属性呢,当使用的时候,属性看起来就像成员,属性和成员有很多相似之处。但是属性有更多独特之处,它可
刚刚发现类还没有写完,还有一个比较大的部分:属性(Property)。

Property在Java和C++里面都是闻所未闻的。通常认为类当中只要有成员和方法就行了。至于属性呢,当使用的时候,属性看起来就像成员,属性和成员有很多相似之处。但是属性有更多独特之处,它可以说是VB的一大特色。我的理解就是属性是为了更好的对成员进行处理而存在的。

属性是这样一种东西,它看起来像是成员,但本质上它是函数。属性的定义是这样的:
public property MyProperty() as Object @#MyProperty是属性的名字
Get @#这个地方不能打括号
return mvarMyProperty
end Get

Set(Byval Value as Object)
mvarMyProperty = Value
end Set
end Property

可以看到,属性其实是由两个函数组成的:Get 和 Set()。当我们读取属性的时候,它就调用Get,所以Get里面必须有return语句;当设置属性的时候,它就调用Set(),所以Set()是带参数的。当外界读取MyProperty的时候,MyProperty就返回mvarMyProperty。mvarMyProperty是事先声明好的变量。当外界设置MyProperty的时候,所赋的值就赋给mvarMyProperty。在这里,mvar-是VB6中缺省使用的前缀,表明这是一个存放属性的变量。

到这里你可能理解了,属性本身不保存数据,它通过另一个变量来读写。但是这又是一件奇怪的事:有必要这么麻烦吗?我直接写:
public MyProperty As Object

不是更简单吗?
这里有一个简单的解释:通过Property,我们可以隐藏真实的成员,比如mvarMyProperty我们就可以定义为:
private mvarMyProperty As Object

这样一来,外界就看不到mvarMyProperty,只能看到MyProperty。当外界对其进行读写的时候,中间就有一个处理过程,用来避免对成员的不正确的赋值。其实对于这种情况,java和C++也有类似的做法,就是使用SetMyProperty()函数和GetMyProperty()函数。VB用Property这种特殊的格式将它们做到一起,显得更简单方便了。

好了,到这里,你不想看看完整的例子吗?这里重新写了一个Human类,当中有一个Age(年龄)属性。我们看看它是怎样阻止把一个人的年龄设为负值的:
imports System

public module MyModule
sub Main
dim LaoWang as new Human
LaoWang.Name = "老王"
LaoWang.Age = 52
LaoWang.Age = 330 @#这句话有没有把老王的年龄设为330岁呢?看看下一句的结果就知道了。
Console.WriteLine("{0}现在{1}岁。", LaoWang.Name, LaoWang.Age)
Console.ReadLine()
end sub
end module

public class Human
public Name as String
dim mvarAge as integer @#这里没有指明是public还是private,因为缺省状态是private

public property Age() as integer
Get
return mvarAge
end Get
Set(Byval Value as integer)
if Value<=0 or Value>=200 then @#通常年龄不应该小于1或大于200
Console.WriteLine(Value & "岁?我死了吗?")
else
mvarAge = value
end if
end set
end property
end class

到这里你应该闭目养神一会儿:原来属性是这样子的啊!








但是话题还没有完。

比如说,如果成员是一个数组,我该怎样为它建立属性呢?为当中的每一个元素建立吗?那数组大小变化了怎么办?Property才不会这么蠢。我们举个例子。比方我们给Human类添加一个数组成员Children,表示一个人有多少个孩子。我们先定义mvarChildren:
dim mvarChildren() as Human

为其建立属性有两种方式。一种是直接将属性的类型设为数组:
public property Children() as Human()
Get
return mvarChildren
end Get
Set(Byval Value as Human())
mvarChildren = value
end Set
end property

那么我们就可以像使用数组一样来使用这个属性了。

另一种是在读取属性的时候传入参数index:
Public Property Children(ByVal index As Integer) As Human
Get
Return mvarChildren(index)
End Get
Set(ByVal Value As Human)
mvarChildren(index) = Value
End Set
End Property

这样可以对传入的下标进行检查。
这里提到读取属性的时候可以给参数。这是很有趣的一个东西。比如老王有3个小孩,其中一个叫“王华”。我想根据名字来得到这个小孩,我可以写一个函数
public function GetChildByName(Byval Name as string) as Human @#内容省略了

然后调用
LaoWang.GetChildByName("王华")

就可以了。
要写成属性的话,我们可以这样写:
public property Child(byval Name as string) as Human
Get
return getChildByName(Name)
end get
set(byval Value as Human)
getChildByName(Name) = Value
end Set
end property

这样,我们就可以直接使用:
LaoWang.Child("王华").Age = 20

这样是不是很方便啊?



原文转自:http://www.ltesting.net