封装概述
面向对象编程中,大多数是以类作为数据封装的基本单位。类将数据和操作数据的方法结合成一个单位。设计类时,不是直接存取类中的数据,而是希望通过方法来存取数据,这样就可以达到封装数据的目的,方便以后的维护升级,也可以在操作数据时多一层判断。
此外,封装还可以解决数据存取的权限问题。可以使用封装将数据隐藏起来,形成一个封闭的空间,然后可以设置哪些数据只能在这个空间使用,哪些数据可以在空间外部使用。如果一个类中包含敏感数据,有些人可以访问,有些人不能访问,若不对这些数据的访问加以限制,后果将非常严重。所以在编写程序时,要对类成员使用不同的访问修饰符,从而定义其访问级别。
封装的意义在于保护或者放置代码(数据)被我们无意中破坏。封装提供了一个有效的保护途径来保护数据不被意外的破坏。相比我们将数据在程序中定义为public,我们将它定义为private的,在很多方面会更好。
私有的数据可以用两种方式来间接的控制。第一种,使用传统的存取方法。第二是使用属性。无论使用哪种方法,我们的目标是在使用数据的同时不破坏任何数据。有以下好处:
- 使用这只需要了解如何通过类的接口来使用类,而不用关心类的内部数据结构和数据组织方法
- 高内聚,低耦合一直是我们追求的,用封装可以减少耦合。
- 只要对外接口不改变,可以任意修改内部实现,这个可以很对的应对各种变化
- 类具加涅清晰的对外接口,降低了使用这的学习过程
封装的实现
1、传统的读写、方法
public class Student
{
private string stuName;
//读方法
public string GetStuName()
{
return stuName;
}
//写方法
public void SetStuName(string name)
{
this.stuName = name;
}
}
通过上满的方法,我们可以保护私有数据不被外部程序破坏。下面使用不同的方法来实现读写数据。
public static void Main(string[] args)
{
Student stu = new student();
stu.SetStuName("Bob");
Console.WriteLine("Name:{0}",stu.stuName);
}
这个例子中,我们不能直接访问Student类中的私有数据stuName,只能通过这两种方法来访问。
2、使用属性
public class Student
{
private string stuName;
public string StuName
{
get{ return stuName;}
set{ stuName = value;}
}
}
public static void Main(string[] args)
{
Student stu = new Student();
stu.stuName = "Bob";
Console.WriteLine("Name:{0}",stu.stuName);
}
上面的例子,我们可以看到如何通过属性来实现封装。属性具有两种操作get和set。get用来返回属性域的值。set通过value这个变量来给属性域赋值。属性可以设为只读的,这只需属性只具有一个get操作。属性也可以设为只写的,这只需属性具有一个set操作。