OOP之封装 【C#】

出自Windows

跳转到: 导航, 搜索

前言

       最近大富翁论坛引发了一场辩论,其实所讨论的就是OO中的封装,大家可以去看看。 
       Url:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3903096 
       封装是OO的三要素之一,也是隔离变化最实用的技巧之一。 

一:封装的概念

       可以把程序按某种规则分成很多“块“,块与块之间可能会有联系,每个块都有一个 

可变部分和一个稳定的部分。我们需要把可变的部分和稳定的部分分离出来,将稳定的部分 暴露给其他块,而将可变的部分隐藏起来,以便于随时可以让它修改。这项工作就是封装.

       例如:在用类实现某个逻辑的时候,类就是以上所说的块,实现功能的具体代码就是 

可变的部分,而public的方法或者属性则是稳定的部分。

       面向对象系统中的对象的封装性可以这么描述: 
       封装性表明对象可以拥有私有元素,并能在隐藏内部细节的情况下管理自己的内部状态, 

外界只能从对象所表达的具体概念,对象所提供的功能[服务]和对象的对外接口来抽象的 认识对象,通过向对象发送消息来激励对象的自身动作,以达到在对象上施加特定操作的目的。

二:封装的好处

       其一: 使用者只需要了解如何通过类的接口使用类,而不用关心类的内部数据结构和数据组织方法。 
       其二:高内聚,低耦合一直是我们所追求的,用好封装恰恰可以减少耦合 
       其三:只要对外接口不改变,可以任意修改内部实现,这个可以很好的应对变化 
       其四:类具有了简洁清晰的对外接口,降低了使用者的学习过程 

三:C#中的访问修饰符

       在C#中使用访问修饰符 public、protected、internal 或 private 来达到封装变化的效果 声明的可访问性 MSDN解释 解释 

private 访问仅限于包含类型 所在类型内部 protected 访问仅限于包含类或从包含类派生的类型 A:所在类型的内部

 B:该类型派生的类型的内部 

protected internal 访问仅限于从包含类派生的当前程序集或类型 A:所在类型的内部

 B:该类型派生的类型的内部 
 C:只有当前项目中可以访问 

internal 访问仅限于当前程序集 只有当前项目中可以访问 public 访问不受限制 访问不受限制

       注:关于程序集的解释,请参看【.NET框架程序设计】<修订版>

三:C#中封装的具体实现

       其一:命名空间级别的封装 
           命名空间 :不能添加任何访问修饰符,永远为public性质 
       其二:类型级别上的封装 
           A:顶级类型 :只能是public和internal ,默认可访问性是 internal。 
           B:嵌套类型 :是其他类型的成员,它们可以具有下表所示的声明的可访问性。 

属于 默认的成员可访问性 该成员允许的声明的可访问性 enum public 无 class private public

 protected 
 internal 
 private 
 protected internal 

interface public 无 struct private public

 internal 
 private 
            注:嵌套类型的可访问性取决于它的可访问域,该域是由已声明的成员可访问性和直接包含类型的可访问域 
            这二者共同确定的。但是,嵌套类型的可访问域不能超出包含它的类型的可访问域。 
       其三:类型级别中的封装【属性或者操作】 
           类型级别中的所有元素都可以用任意的访问修饰符做访问限制 
           A:构造函数 
               可以控制构造函数为private来实现单例模式 
           B:字段 
               字段除了可以使用访问修饰符来限制其访问级别以外,由于它的特殊性,还需要有别的封装处理。 
               类的成员一般可以读和写。但是在某些特殊情况下,是只能读或者只能写的。 
               所以C#中,引入了属性的概念。利用属性,我们可以限制字段为只读或者只写或者可读写。 
               Person类一般在定义了名字以后,使用者是不能修改的,如何做到只读效果呢?我们可以这样: 
                        public String sName { get; private set; } // read-only
                        public String sCode { private get; set; } // write-only
              Person类中有Age,而年龄是有限制的,假设只能 Age大于0,小于<100,如何做到呢? 
                        public Int32 Age 
                        { 
                             get { return Age; } 
                             set 
                             { 
                                  if (value <= 0 || value > 100)
                                        throw new Exception("年龄给值错误"); 
                                  Age = value;
                             } 
                       } 
           C:方法 
               我们一般把不使用或者容易变化的方法定义成private 
               而把常使用比较稳定的方法定义成public 
           D:嵌套类型 :见嵌套类型 

四:封装的原则:

       简化用户接口,隐藏实现细节,这个是封装的根本目的。 
       封装的难点在于如何设计接口。 
       其一:必须保证接口是功能的全集,即接口能够覆盖所有需求。 
               不能完成必要功能的封装是没有意义的。 
       其二:尽量使接口是最小冗余的。这是为了简化类使用者的学习和使用,难用的接口是 
               最容易让人遗忘的。冗余接口的存在是被允许的,但必须保证冗余接口是有效的。 
               也就是说,增加冗余接口会带来很大的好处,比如性能的飞升。 
       其三:要保证接口是稳定的,将接口和实现分离,并将实现隐藏,就是为了能保护类使用者 
               在类的实现细节改变的情况下,不必随时修改。一旦接口被公布,永远也不要改变它。 
       绝大多数失败的设计,都来自于失败的封装!
个人工具
友情链接