OOP之封装 【C#】

前言
        最近大富翁论坛引发了一场辩论,其实所讨论的就是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:嵌套类型 :见嵌套类型

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

你可能感兴趣的:(数据结构,c,exception,String,C#,oop)