属性是字段向方法的过渡
1
publicclassPerson
2

{
3
4
publicintage;//直接公开字段,无法控制用户输入非法的值
5
6
7
//Java模式的对Age控制方式,需要两个方法,Get和Set。麻烦麻烦阿!
8
publicintGetAge()
9

{
10
returnAge;
11
}
12
13
publicvoidSetAge(intpersonAge)
14

{
15
if(personAge<18)
16

{
17
personAge=18;
18
}
19
if(personAge>81)
20

{
21
personAge=81;
22
}
23
age=personAge;
24
}
25
26
//C#模式的Age控制方式,Set和Get是属性的两个访问器,管理方便
27
publicintAge
28

{
29
set
30

{
31
if(value<18)
32

{
33
value=18;
34
}
35
if(value>81)
36

{
37
value=81;
38
}
39
age=value;
40
}
41
get
42

{
43
returnage;
44
}
45
46
}
47
48
}
publicclassPerson2


{3

4
publicintage;//直接公开字段,无法控制用户输入非法的值5

6

7
//Java模式的对Age控制方式,需要两个方法,Get和Set。麻烦麻烦阿!8
publicintGetAge()9


{10
returnAge;11
}12

13
publicvoidSetAge(intpersonAge)14


{15
if(personAge<18)16


{17
personAge=18;18
}19
if(personAge>81)20


{21
personAge=81;22
}23
age=personAge;24
}25

26
//C#模式的Age控制方式,Set和Get是属性的两个访问器,管理方便27
publicintAge28


{29
set30


{31
if(value<18)32


{33
value=18;34
}35
if(value>81)36


{37
value=81;38
}39
age=value;40
}41
get42


{43
returnage;44
}45

46
}47

48
}
现在我们来看一个应用,描述部门和员工的一对多的关系。先看一个错误的设计:
1
publicclassSpace
2

{
3
4
publicstaticvoidMain(string[]args)
5

{
6
Departmentdep=newDepartment();
7
//错误一,Staffs所存储的值类型无法被控制。Staffs又可以放字符串,又可以放对象 数据无法统一。
8
dep.Staffs.Add("leo");//放字符串
9
dep.Staffs.Add(newStaff("King"));//放对象
10
11
//错误二,一旦Department对Staffs的设计改变(比如用数组描述),遍历代码就要改变
//遍历1:类Department将Staffs描述为字符串
12
for(inti=0;i<=dep.Staffs.Count-1;i++)
13

{
14
System.Console.WriteLine(dep.Staffs[i]);
15
}
16
//遍历2:类Department将Staffs描述为数组
17
for(inti=0;i<=dep.Staffs.Length-1;i++)
18

{
19
System.Console.WriteLine(dep.Staffs[i]);
20
}
21
//造成用户必须根据Staffs数据描述的方式不同而编写不同的代码的原因为类Department设计不合理。
22
}
23
}
24
25
publicclassDepartment
26

{
27
//这是一个错误的设计,向用户暴露了Staffs的数据结构
28
publicSystem.Collections.ArrayListStaffs=newSystem.Collections.ArrayList();
29
}
30
31
publicclassDepartment
32

{
33
//这是一个错误的设计,向用户暴露了Staffs的数据结构
34
publicStaff[]Staffs=newStaff[]
{newStaff("leo"),newStaff("King")};
35
}
36
37
publicclassStaff
38

{
39
publicStaff(stringname)
40

{
41
Name=name;
42
}
43
44
publicstringName;
45
}
publicclassSpace2


{3

4
publicstaticvoidMain(string[]args)5


{6
Departmentdep=newDepartment();7
//错误一,Staffs所存储的值类型无法被控制。Staffs又可以放字符串,又可以放对象 数据无法统一。8
dep.Staffs.Add("leo");//放字符串9
dep.Staffs.Add(newStaff("King"));//放对象10

11
//错误二,一旦Department对Staffs的设计改变(比如用数组描述),遍历代码就要改变//遍历1:类Department将Staffs描述为字符串
12
for(inti=0;i<=dep.Staffs.Count-1;i++)13


{14
System.Console.WriteLine(dep.Staffs[i]);15
}16

//遍历2:类Department将Staffs描述为数组
17
for(inti=0;i<=dep.Staffs.Length-1;i++)18


{19
System.Console.WriteLine(dep.Staffs[i]);20
}21

//造成用户必须根据Staffs数据描述的方式不同而编写不同的代码的原因为类Department设计不合理。
22
}23
}24

25
publicclassDepartment26


{27
//这是一个错误的设计,向用户暴露了Staffs的数据结构28
publicSystem.Collections.ArrayListStaffs=newSystem.Collections.ArrayList();29
}30

31
publicclassDepartment32


{33
//这是一个错误的设计,向用户暴露了Staffs的数据结构34

publicStaff[]Staffs=newStaff[]
{newStaff("leo"),newStaff("King")};35
}36

37
publicclassStaff38


{39
publicStaff(stringname)40


{41
Name=name;42
}43

44
publicstringName;45
}
好的设计方法是向用户关闭数据结构的细节
1
publicclassSpace
2

{
3
4
publicstaticvoidMain(string[]args)
5

{
6
Departmentdep=newDepartment();
7
//无论将来Staffs的数据结构有什么变化,调用的代码不会有变化
8
dep.AddStaff(newStaff("leo"));
9
dep.AddStaff(newStaff("King"));
10
for(inti=0;i<=dep.StaffsCount-1;i++)
11

{
12
System.Console.WriteLine(dep.GetStaffFromIndex(i).Name);
13
}
14
}
15
}
16
17
publicclassDepartment
18

{
19
//这是正确的设计
20
privateSystem.Collections.ArrayListStaffs=newSystem.Collections.ArrayList(); //private隐藏了Staffs的数据结构
21
22
publicintStaffsCount //统一遍历代码
23

{
24
get
25

{
26
returnStaffs.Count;
27
}
28
}
29
30
publicintAddStaff(Staffstaff) //统一Staffs的数据结构
31

{
32
returnthis.Staffs.Add(staff);
33
}
34
35
publicvoidRemove(Staffstaff)
36

{
37
this.Staffs.Remove(staff);
38
}
39
40
publicStaffGetStaffFromIndex(intindex)
41

{
42
return(Staff)this.Staffs[index];
43
}
44
45
}
46
47
publicclassStaff
48

{
49
publicStaff(stringname)
50

{
51
Name=name;
52
}
53
54
publicstringName;
55
}
publicclassSpace2


{3

4
publicstaticvoidMain(string[]args)5


{6
Departmentdep=newDepartment();7
//无论将来Staffs的数据结构有什么变化,调用的代码不会有变化8
dep.AddStaff(newStaff("leo"));9
dep.AddStaff(newStaff("King"));10
for(inti=0;i<=dep.StaffsCount-1;i++)11


{12
System.Console.WriteLine(dep.GetStaffFromIndex(i).Name);13
}14
}15
}16

17
publicclassDepartment18


{19
//这是正确的设计20
privateSystem.Collections.ArrayListStaffs=newSystem.Collections.ArrayList(); //private隐藏了Staffs的数据结构21

22
publicintStaffsCount //统一遍历代码23


{24
get25


{26
returnStaffs.Count;27
}28
}29

30
publicintAddStaff(Staffstaff) //统一Staffs的数据结构31


{32
returnthis.Staffs.Add(staff);33
}34

35
publicvoidRemove(Staffstaff)36


{37
this.Staffs.Remove(staff);38
}39

40
publicStaffGetStaffFromIndex(intindex)41


{42
return(Staff)this.Staffs[index];43
}44

45
}46

47
publicclassStaff48


{49
publicStaff(stringname)50


{51
Name=name;52
}53

54
publicstringName;55
}
如果我们引入索引器,那代码能更合理
1
publicclassSpace
2

{
3
4
publicstaticvoidMain(string[]args)
5

{
6
Departmentdep=newDepartment();
7
//无论将来Staffs的数据结构有什么变化,调用的代码不会有变化
8
dep.AddStaff(newStaff("leo"));
9
dep.AddStaff(newStaff("King"));
10
for(inti=0;i<=dep.StaffsCount-1;i++)
11

{
12
System.Console.WriteLine(dep[i].Name);//注意下标
13
}
14
}
15
}
16
17
publicclassDepartment
18

{
19
//这是正确的设计
20
privateSystem.Collections.ArrayListStaffs=newSystem.Collections.ArrayList();
21
22
publicintStaffsCount
23

{
24
get
25

{
26
returnStaffs.Count;
27
}
28
}
29
30
publicintAddStaff(Staffstaff)
31

{
32
returnthis.Staffs.Add(staff);
33
}
34
35
publicvoidRemove(Staffstaff)
36

{
37
this.Staffs.Remove(staff);
38
}
39
40
publicStaffthis[intindex]
41

{
42
set
43

{
44
Staff[index]=value;
45
}
46
get
47

{
48
return(Staff)Staff[index];
49
}
50
}
51
52
}
publicclassSpace2


{3

4
publicstaticvoidMain(string[]args)5


{6
Departmentdep=newDepartment();7
//无论将来Staffs的数据结构有什么变化,调用的代码不会有变化8
dep.AddStaff(newStaff("leo"));9
dep.AddStaff(newStaff("King"));10
for(inti=0;i<=dep.StaffsCount-1;i++)11


{12
System.Console.WriteLine(dep[i].Name);//注意下标 13
}14
}15
}16

17
publicclassDepartment18


{19
//这是正确的设计20
privateSystem.Collections.ArrayListStaffs=newSystem.Collections.ArrayList();21

22
publicintStaffsCount23


{24
get25


{26
returnStaffs.Count;27
}28
}29

30
publicintAddStaff(Staffstaff)31


{32
returnthis.Staffs.Add(staff);33
}34

35
publicvoidRemove(Staffstaff)36


{37
this.Staffs.Remove(staff);38
}39

40
publicStaffthis[intindex]41


{42
set43


{44
Staff[index]=value;45
}46
get47


{48
return(Staff)Staff[index];49
}50
}51

52
}
注意代码的第40的变化,不过在一个类中,只能有一个this[int index]。
注意使用了第40行的索引器,第12行可以象数组下标一样用啦。
不过,这样的设计还不完善,请看下篇,初见继承威力。
1093

被折叠的 条评论
为什么被折叠?



