属性和索引器

简介:

属性是字段向方法的过渡
 

1 public   class  Person
2   {
3
4 public int age;//直接公开字段,无法控制用户输入非法的值
5
6
7 //Java模式的对Age控制方式,需要两个方法,Get和Set。麻烦麻烦阿!
8 public int GetAge()
9 {
10 return Age;
11 }

12
13 public void SetAge(int personAge)
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 public int Age
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 return age;
44 }

45 
46 }

47 
48 }

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

 

1   public   class  Space
2   {
3
4 public static void Main(string[] args)
5 {
6 Department dep = new Department();
7 //错误一,Staffs所存储的值类型无法被控制。Staffs又可以放字符串,又可以放对象 数据无法统一。
8 dep.Staffs.Add("leo"); //放字符串
9 dep.Staffs.Add(new Staff("King")); //放对象
10
11 //错误二,一旦Department对Staffs的设计改变(比如用数组描述),遍历代码就要改变
//遍历1:类Department将Staffs描述为字符串
12 for (int i = 0; i <= dep.Staffs.Count - 1; i++)
13 {
14 System.Console.WriteLine(dep.Staffs[i]);
15 }

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

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

23 }

24
25   public   class  Department
26   {
27 //这是一个错误的设计,向用户暴露了Staffs的数据结构
28 public System.Collections.ArrayList Staffs = new System.Collections.ArrayList();
29 }

30
31   public   class  Department
32   {
33 //这是一个错误的设计,向用户暴露了Staffs的数据结构
34 public Staff[] Staffs = new Staff[] new Staff("leo"), new Staff("King") };
35 }

36
37   public   class  Staff
38   {
39 public Staff(string name)
40 {
41 Name = name;
42 }

43
44 public string Name;
45 }


好的设计方法是向用户关闭数据结构的细节
 

1   public   class  Space
2   {
3
4 public static void Main(string[] args)
5 {
6 Department dep = new Department();
7 //无论将来Staffs的数据结构有什么变化,调用的代码不会有变化
8 dep.AddStaff(new Staff("leo"));
9 dep.AddStaff(new Staff("King"));
10 for (int i = 0; i <= dep.StaffsCount - 1;i++ )
11 {
12 System.Console.WriteLine(dep.GetStaffFromIndex(i).Name);
13 }

14 }

15 }

16
17   public   class  Department
18   {
19 //这是正确的设计
20 private System.Collections.ArrayList Staffs = new System.Collections.ArrayList(); //private隐藏了Staffs的数据结构
21
22 public int StaffsCount //统一遍历代码
23 {
24 get
25 {
26 return Staffs.Count;
27 }

28 }

29
30 public int AddStaff(Staff staff) //统一Staffs的数据结构
31 {
32 return this.Staffs.Add(staff);
33 }

34
35 public void Remove(Staff staff)
36 {
37 this.Staffs.Remove(staff); 
38 }

39
40 public Staff GetStaffFromIndex(int index)
41 {
42 return (Staff)this.Staffs[index];
43 }

44
45 }

46
47   public   class  Staff
48   {
49 public Staff(string name)
50 {
51 Name = name;
52 }

53
54 public string Name;
55 }

如果我们引入索引器,那代码能更合理
 

1   public   class  Space
2   {
3
4 public static void Main(string[] args)
5 {
6 Department dep = new Department();
7 //无论将来Staffs的数据结构有什么变化,调用的代码不会有变化
8 dep.AddStaff(new Staff("leo"));
9 dep.AddStaff(new Staff("King"));
10 for (int i = 0; i <= dep.StaffsCount - 1;i++ )
11 {
12 System.Console.WriteLine(dep[i].Name); //注意下标 
13 }

14 }

15 }

16
17   public   class  Department
18   {
19 //这是正确的设计
20 private System.Collections.ArrayList Staffs = new System.Collections.ArrayList();
21
22 public int StaffsCount
23 {
24 get
25 {
26 return Staffs.Count;
27 }

28 }

29
30 public int AddStaff(Staff staff)
31 {
32 return this.Staffs.Add(staff);
33 }

34
35 public void Remove(Staff staff)
36 {
37 this.Staffs.Remove(staff); 
38 }

39
40 public Staff this[int index]
41 {
42 set
43 {
44 Staff[index] = value;
45 }

46 get
47 {
48 return (Staff)Staff[index];
49 }

50 }

51
52 }


注意代码的第40的变化,不过在一个类中,只能有一个this[int index]。
注意使用了第40行的索引器,第12行可以象数组下标一样用啦。

不过,这样的设计还不完善,请看下篇,初见继承威力。


本文转自shyleoking 51CTO博客,原文链接:http://blog.51cto.com/shyleoking/806278


相关文章
|
关系型数据库 MySQL Apache
window下修改MySQL密码
window下修改MySQL密码
412 6
|
存储 C语言
关于如何解决C语言中缓冲区溢出问题
关于如何解决C语言中缓冲区溢出问题
475 0
|
6月前
|
SQL Java 关系型数据库
Dataphin功能Tips系列(53)-离线集成任务如何合理配置JVM资源
本文探讨了将MySQL数据同步至Hive时出现OOM问题的解决方案。
164 5
|
12月前
|
人工智能 安全 大数据
元宇宙游戏:沉浸式体验的新纪元
在科技飞速发展的今天,元宇宙游戏作为融合了虚拟现实(VR)、增强现实(AR)、人工智能(AI)与区块链等前沿技术的数字新世界,正引领我们进入一个前所未有的沉浸式体验时代。本文将深入探讨元宇宙游戏的特点、技术基础及其如何引领沉浸式体验的新潮流。
|
前端开发 JavaScript C++
【绝技大公开】Webpack VS Rollup:一场前端工程化领域的巅峰对决,谁能笑到最后?——揭秘两大构建神器背后的秘密与奇迹!
【8月更文挑战第12天】随着前端技术的发展,模块化与自动化构建成为标准实践。Webpack与Rollup作为主流构建工具,各具特色。Webpack是一款全能型打包器,能处理多种静态资源,配置灵活,适合复杂项目;Rollup专注于ES6模块打包,利用Tree Shaking技术减少冗余,生成更精简的代码。Rollup构建速度快,配置简洁,而Webpack则拥有更丰富的插件生态系统。选择合适的工具需根据项目需求和个人偏好决定。两者都能有效提升前端工程化水平,助力高质量应用开发。
217 1
|
机器学习/深度学习 API Python
机器学习特征降维
这篇内容概述了特征降维在机器学习中的重要性,包括三个主要方法:低方差过滤法、PCA(主成分分析)和相关系数法。低方差过滤法通过删除方差低于阈值的特征来减少无关信息;PCA通过正交变换降低数据的维数,保留大部分信息;相关系数法(如皮尔逊和斯皮尔曼相关系数)用于评估特征间的相关性,去除高度相关的特征以简化模型。这些技术有助于提高模型效率和泛化能力。
|
机器学习/深度学习 数据采集 监控
构建一个基于机器学习的图像识别系统
【5月更文挑战第29天】构建基于机器学习的图像识别系统涉及数据准备、模型选择、训练优化及部署测试。数据准备包括收集多样化数据集、预处理和数据划分;模型选择常选用CNN、RNN/LSTM或GAN;训练优化涉及模型训练、评估与选择;最后,部署到实际应用时要考虑计算效率和内存占用,并持续更新维护模型。
|
网络协议 安全 Linux
解密TCP连接断开:四次挥手的奥秘和数据传输的安全
本文将介绍TCP连接的断开过程,重点关注四次挥手的过程和状态变迁,以及为什么挥手需要四次和为什么需要TIME_WAIT状态。在TCP连接断开的过程中,双方需要发送FIN和ACK报文来确保数据的可靠传输和连接的正确关闭。挥手需要四次的原因是为了确保数据的完整传输和连接的可靠关闭。
1042 1
解密TCP连接断开:四次挥手的奥秘和数据传输的安全
|
Kubernetes Cloud Native 测试技术
「译文」深入了解 Kubernetes 和 Nomad
「译文」深入了解 Kubernetes 和 Nomad
|
存储 开发工具 数据安全/隐私保护
版本控制:让你的代码有迹可循
版本控制:让你的代码有迹可循