当前位置:早雪网网络学院编程文档C# → <展现C#> 第五章 类 (2)

<展现C#> 第五章 类 (2)

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-22 19:52:18
   evsrc.TriggerEvent();
31:  }
32:
33:  public static void CatchEvent(string strText)
34:  {
35:   Console.WriteLine(strText);
36:  }
37:
38:  public void InstanceCatch(string strText)
39:  {
40:   Console.WriteLine("Instance " + strText);
41:  }
42: }

    第4行声明了代表元(事件方法原形),它用来给第8行中的EventSource类声明TextOut事件域成员。你可以观察到代
表元作为一种新的类型声明,当声明事件时可以使用代表元。
    该类仅有一个方法,它允许我们触发事件。请注意,你必须进行事件域成员不为null的检测,因为可能会出现没有客
户对事件感兴趣这种情况。
    TestApp类包含了Main 方法,也包含了另外两个方法,它们都具备事件所必需的信号。其中一个方法是静态的,而另
一个是实例方法。
    EventSource 被实例化,而静态方法CatchEvent被预关联上了 TextOut事件:
evsrc.TextOut += new EventHandler(CatchEvent);
    从现在起,当事件被触发时,该方法被调用。如果你对事件不再感兴趣,简单地取消关联:
evsrc.TextOut -= new EventHandler(CatchEvent);
    注意,你不能随意取消关联的处理函数——在类代码中仅创建了这些处理函数。为了证明事件处理函数也和实例方法
一起工作,余下的代码建立了TestApp 的实例,并钩住事件处理方法。
    事件在哪方面对你特别有用?你将经常在ASP+中或使用到WFC (Windows Foundation Classes)时,涉及到事件和代表
元。

5.5   应用修饰符
    在这一章的学习过程中,你已经见过了象public、virtual等修饰符。欲以一种易于理解的方法概括它们,我把它们划
分为三节:

。类修饰符
。成员修饰符
。存取修饰符

5.5.1 类修饰符
    到目前为止,我还没有涉及到类修饰符,而只涉及到了应用于类的存取修饰符。但是,有两个修饰符你可以用于类:
    abstract——关于抽象类的重要一点就是它不能被实例化。只有不是抽象的派生类才能被实例化。派生类必须实现抽
象基类的所有抽象成员。你不能给抽象类使用sealed 修饰符。
     sealed——密封 类不能被继承。使用该修饰符防止意外的继承,在.NET框架中的类用到这个修饰符。
    要见到两个修饰符的运用,看看清单5.12 ,它创建了一个基于一个抽象类的密封类(肯定是一个十分极端的例子)。

清单  5.12  抽象类和密封类

1: using System;
2:
3: abstract class AbstractClass
4: {
5:  abstract public void MyMethod();
6: }
7:
8: sealed class DerivedClass:AbstractClass
9: {
10:  public override void MyMethod()
11:  {
12:   Console.WriteLine("sealed class");
13:  }
14: }
15:
16: public class TestApp
17: {
18:  public static void Main()
19:  {
20:   DerivedClass dc = new DerivedClass();
21:   dc.MyMethod();
22:  }
23: }

5.5.2  成员修饰符
    与有用的成员修饰符的数量相比,类修饰符的数量很少。我已经提到了一些,这本书即将出现的例子描述了其它的成
员修饰符。
    以下是有用的成员修饰符:
        abstract——说明一个方法或存取标志不能含有一个实现。它们都是隐式虚拟,且在继承类中,你必须提供
override关键字。
     const——这个修饰符应用于域成员或局部变量。在编译时常量表达式被求值,所以,它不能包含变量的引用。
    event ——定义一个域成员或属性作为类型事件。用于捆绑客户代码到类的事件。
    extern——告诉编译器方法实际上由外部实现。第10章 “和非受管代码互相操作” 将全面地涉及到外部代码。
    override——用于改写任何基类中被定义为virtual的方法和存取标志。要改写的名字和基类的方法必须一致。
    readonly——一个使用  readonly修饰符的域成员只能在它的声明或者在包含它的类的构造函数中被更改。

    static——被声明为static的成员属于类,而不属于类的实例。你可以用static 于域成员、方法、属性、操作符甚至
构造函数。
    virtual——说明方法或存取标志可以被继承类改写。

5.5.3  存取修饰符
    存取修饰符定义了某些代码对类成员(如方法和属性)的存取等级。你必须给每个成员加上所希望的存取修饰符,否
则,默认的存取类型是隐含的。
    你可以应用4个 存取修饰符之一:
    public——任何地方都可以访问该成员,这是具有最少限制的存取修饰符。
    protected——在类及所有的派生类中可以访问该成员,不允许外部访问。
    private——仅仅在同一个类的内部才能访问该成员。甚至派生类都不能访问它。
    internal——允许相同组件(应用程序或库)的所有代码访问。在.NET组件级别,你可以把它视为public,而在外部
则为private。
    为了演示存取修饰符的用法,我稍微修改了Triangle例子,使它包含了新增的域成员和一个新的派生类(见清单
5.13)。

清单 5.13  在类中使用存取修饰符

1: using System;
2:
3: internal class Triangle
4: {
5:  protected int m_a, m_b, m_c;
6:  public Triangle(int a, int b, int c)
7:  {
8:   m_a = a;
9:   m_b = b;
10:   m_c = c;
11:  }
12:
13:  public virtual double Area()
14:  {
15:   // Heronian formula
16:   double s = (m_a + m_b + m_c) / 2.0;
17:   double dArea = Math.Sqrt(s*(s-m_a)*(s-m_b)*(s-m_c));
18:   return dArea;
19:  }
20: }
21:
22: internal class Prism:Triangle
23: {
24:  private int m_h;
25:  public Prism(int a, int b, int c, int h):base(a,b,c)
26:  {
27:   m_h = h;
28:  }
29:
30:  public override double Area()
31:  {
32:   double dArea = base.Area() * 2.0;
33:   dArea += m_a*m_h + m_b*m_h + m_c*m_h;
34:   return dArea;
35:  }
36: }
37:
38: class PrismApp
39: {
40:  public static void Main()
41:  {
42:   Prism prism = new Prism(2,5,6,1);
43:   Console.WriteLine(prism.Area());
44:  }
45: }

        Triangle 类和 Prism 类现在被标为 internal。这意味着它们只能在当前组件中被访问。请记住“.NET组件”这
个术语指的是包装( packaging,),而不是你可能在COM+中用到的组件。Triangle 类有三个 protected成员,它们在构
造函数中被初始化,并用于面积计算的方法中。由于这些成员是protected 成员,所以我可以在派生类Prism中访问它们,
在那里执行不同的面积计算。Prism自己新增了一个成员m_h,它是私有的——甚至派生类也不能访问它。
      花些时间为每个类成员甚至每个类计划一种保护层次,通常是个好主意。当需要引入修改时,全面的计划最终会帮
助你,因为没有程序员会愿意使用“没有文档”的类功能。
5.6  小结
    这章显示了类的各种要素,它是运行实例(对象)的模

上一页  [1] [2] [3]  下一页

[数据载入中...] [返回上一页] [打 印]