代码改变世界

C#语言学习笔记二

2009-03-14 22:59  张智清  阅读(408)  评论(0编辑  收藏  举报

C# 2.0面向对象编程——议OOP三大支柱

当显式地引用当前对象的字段和成员时,就需要使用C#this关键字。往往使用C#this进行自引用来解决名称冲突(一般是参数名称和内部状态变量名称之间的冲突)。

静态成员在其方法作用域中不能使用this关键字。这是有意义的,因为静态成员函数在类(而不是对象)级别上操作,没有this

this关键字的另一个用处是:强制一个构造函数调用另一个构造函数,以避免冗余的成员初始化逻辑。(即使用this转发构造函数调用

类的公共接口是指通过点运算符从一个对象变量可以直接访问到的成员集合。

C#的封装支持:

★ 封装的核心是:对象的字段数据不应该从公共接口直接访问。如果用户想改变对象的状态,则是通过间接地使用访问方法(get)和修改方法(set)。就是说封装提供了一种保护状态数据完整性的方法——定义私有数据字段。定义私有字段的主要方式有二:

使用传统的访问方法和修改方法执行封装

定义一对传统的访问方法(获取方法)和修改方法(设置方法),例如:

public class Employee

{

       private string fullName;

       public string GetFullName() { return fullName;}

       public void SetFullName(string n)

       {

              //删除非法字符,检验合法字符等;

              fullName=n;

       }

}

 

       定义一个命名的属性:类属性(property

.NET语言更喜欢使用属性property)来封装,属性可以模仿可以公开访问的数据字段。

C#属性是由一个获取(get)代码块(访问器)和一个设置(set)代码块(修改器)组成的。C#value标记代表赋值号的右边。value标记的底层数据类型取决于它所表示的数据的种类。

public class Employee

{

       private int empID;

       private float currPay;

       private string fullName;

 

       public  int  ID

       {

              get{ return empID;}

              set

              {

                     //检验传入的值

                     empID=value;

              }

       }

       public string Name

       {

              get{ return  fullName;}

              set{ fullName=value;}

       }

       public float Pay

       {

              get{ return  currPay;}

              set{ currPay=value;}

       }

}

       C#属性的内部表现:C#属性其实在底层都要映射到一个get_set_对。

C#的继承支持:

       继承有两种:传统继承(is-a关系)和包含/委托模型(has-a关系)。

       在类之间建立is-a关系,就在类型之间建立了依赖。传统继承背后的基本思想是:新的类可以使用(并且可能扩展)其他类的功能

       继承保持了封装。因此,派生类不能直接访问其基类定义的私有成员。

       如果不另外指定,子类的构造函数自动调用其父类的默认构造函数

       C#中,除非另外指定,基类的默认构造函数是在执行自定义的子类构造函数逻辑之前自动调用的。在这以后,自定义构造函数才开始访问基类的众多公共属性来建立其状态。

       使用C#base关键字来调用基类的自定义构造函数。这样就可以优化派生类的创建。

       作为一般的规则,所有的子类应该显式调用一个合适的基类构造函数

       在任何子类想访问由父类定义的公共或受保护成员时,都可以使用base关键字。base关键字的使用并不限制在构造函数逻辑中

       在基类中定义受保护成员的好处是:继承类型不再需要使用公共的方法或属性来访问数据了。

       不能从对象的实例访问受保护数据

       防止继承:密封类。使用C#sealed关键字来声明某个类是密封的,不允许作为其他任何类型的基类。

       如果想创建一个新类使用密封类的功能,唯一的选择就是放弃传统继承,使用包含/委托模型(即has-a关系)

       嵌套类型:在C#中,可以直接在一个类或结构的作用域中定义一个类型(枚举、类、接口、结构或委托)。

       嵌套类型类似于组合(),但使用嵌套类型,我们可以完全控制内部类型而不是被包含对象的访问级别

       因为嵌套类型是包含类的一个成员,所有它可以访问包含类的私有成员

       通常情况下,嵌套类型只对外部类起辅助作用,而不是为了给外部世界使用的。

       如果想在包含类型之外使用嵌套类型,必须通过包含类型的作用域来限定它。而且唯有公共嵌套类型才可以被任何人使用;私有嵌套类型只能被其包含类的成员使用。

 

C#的多态支持

怎样让相关的对象对同样的请求做出不同的响应?——多态机制。多态给子类提供了一种方式,可以自定义如何实现基类所定义的方法

虚方法:virtual关键字

       子类使用override关键字重写基类的虚方法,并且在重写时仍然可以通过base关键字重用(也可能扩展)父类的默认行为。

       sealed关键字也可以应用到类型成员上,以防止虚成员将来被继承类型所重写。

抽象类:abstract关键字

       C#中使用abstract关键字来声明抽象类以防止此类被直接实例化。

       当类被定义为抽象基类时,它可以定义任意数量的抽象方法。抽象方法可以用来定义不提供默认实现的方法

       抽象方法只能在抽象类中定义

       继承抽象类的子类被强制要实现该抽象类的所有抽象方法,否则该子类只能被认为也是不可创建的抽象类型,必须用abstract关键字修饰。

       成员隐藏:如果一个派生类重定义了一个继承自基类的相同的成员,派生类就隐藏(或遮蔽)了父成员。处理方式有二:

A.使用override关键字修改扩展父类的默认行为。

B. 或使用new关键字修饰来显式地声明,派生类型的实现是明确设计为隐藏父类的版本的。

       使用显式强制类型转换调用一个已遮蔽成员的基类实现仍然是可行的。

 

C#语言提供了三种判断给定基类引用是否实际上引用的是继承类型的方式:

A.显式类型转换

B. is关键字,它返回一个代表基类引用是否与给定的继承类型兼容的布尔值。

C. as关键字来获得一个对继承类型的引用(如果类型间不兼容,引用被设置为null)。