C#中的类定义

  C#使用 class 关键字来定义类:

  1. class MyClass
  2. {
  3. // Class members.
  4. }

  这段代码定义了一个类 MyClass。定义了一个类后,就可以在项目中能访问该定义的其他位置对该类进行实例化。默认情况下,类声明为内部的,即只有当前项目中的代码才能访问它。可使用 internal 访问修饰符关键字来显式地指定这一点,如下所示(但这是不必要的):

  1. internal class MyClass
  2. {
  3. // Class members.
  4. }

  另外,还可以指定类时公共的,可由其他项目中的代码来访问。为此,要使用关键字 public

  1. public class MyClass
  2. {
  3. // Class members.
  4. }
  采用这种方式声明的类不能是私有或受保护的。可以把这些声明类的修饰符用于声明类成员,详见第 10 章。

  除了这两个访问修饰符关键字外,还可以指定类是抽象的(不能实例化,只能继承,可以有抽象成员)或密封的( sealed,不能继承)。为此,可使用两个互斥的关键字 abstractsealed。所以,必须使用下述方式声明抽象类:

  1. public abstract class MyClass
  2. {
  3. // Class members, may be abstact.
  4. }

  其中 MyClass 是一个公共抽象类,也可以是内部抽象类。

  密封类的声明如下所示:

  1. public sealed class MyClass
  2. {
  3. // Class members.
  4. }

  与抽象类一样,密封类也可以是公共或内部的。

  还可以在类定义中指定继承。为此,要在类名的后面加上一个冒号,其后是基类名,例如:

  1. public class MyClass : MyBase
  2. {
  3. // Class members.
  4. }

  注意 ⚠️,在 C#的类定义中,只能有一个基类。如果继承了一个抽象类,就必须实现所继承的所有抽象成员(除非派生类也是抽象的)。

  编译器不允许派生类的可访问性高于基类。也就是说,内部类可以继承于一个公用基类,但公共类不能继承于一个内部类。因此,下述代码是合法的:

  1. public class MyBase
  2. {
  3. // Class members.
  4. }
  5. internal class MyClass : MyBase
  6. {
  7. // Class members.
  8. }

  但下述代码不能编译:

  1. internal class MyBase
  2. {
  3. // Class members.
  4. }
  5. public class MyClass : MyBase
  6. {
  7. // Class members.
  8. }

  如果没有使用基类,则被定义的类就只能继承于基类 System.Object(它在 C#中的别名是 object )。毕竟,在继承层次结构中,所有类的根都是 System.Object,稍后将详细介绍这个基类。

  除了以这种方式指定基类外,还可以在冒号之后指定支持的接口。如果指定了基类,它必须紧跟在冒号的后面,之后才是指定的接口。如果未指定基类,则接口就跟在冒号的后面。必须使用逗号来分隔基类名(如果有基类)和接口名。

  例如,给 MyClass 添加一个接口,如下所示:

  1. public class MyClass : IMyInterface
  2. {
  3. // Class members.
  4. }

  支持该接口的类必须实现所有接口成员,但如果不想使用给定的接口成员,就可以提供一个 “空”的实现方式(没有函数代码)。还可以把接口成员实现为抽象类中的抽象成员。

  下面的声明是无效的,因为基类 MyBase 不是继承列表中的第一项:

  1. public class MyClass : IMyInterface, MyBase
  2. {
  3. // Class members.
  4. }

  指定基类和接口的正确方式如下:

  1. public class MyClass : MyBase, IMyInterface
  2. {
  3. // Class members.
  4. }

  可以指定多个接口,所以下列代码也是有效的:

  1. public class MyClass : MyBase, IMyInterface, IMySecondInterface
  2. {
  3. // Class members.
  4. }

  表 9-1 是类定义中可以使用的访问修饰符的组合。

修饰符含义
无或 internal只能在当前项目中访问类
public可以在任何地方访问类
abstract 或 internal abstract类只能在当前项目中访问,不能实例化,只能被继承
public abstract类可以在任何地方访问,不能实例化,只能被继承
sealed或internal sealed类只能在当前项目中访问,不能被继承,只能实例化
public sealed类可以在任何地方访问,不能被继承,只能实例化

表9-1 类定义可以使用的访问修饰符

  接口的定义

  声明接口的方式与声明类的方式相似,但使用的关键字 interface,而不是 class,例如:

  1. interface IMyInterface
  2. {
  3. // Interface members.
  4. }

  访问修饰符关键字 publicinternal 的使用方式是相同的,与类一样,接口也默认定义为内部接口。所以要使接口可以公开访问,必须使用 public 关键字:

  1. public interface IMyInterface
  2. {
  3. // Interface members.
  4. }

  不能在接口中使用关键字 abstractsealed,因为这两个修饰符在接口定义中是没有意义的(它们不包含实现代码,所以不能直接实例化,且必须是可以继承的)。

  也可以与类继承类似的方式来指定接口的继承。主要的区别是可以使用多个基接口,例如:

  1. public interface IMyInterface : IMyBaseInterface, IMyBaseInterface2
  2. {
  3. // Interface members.
  4. }
  接口不是类,所以没有继承 System.Object。但为了方便起见,System.Object的成员可以通过接口类型的变量来访问。如上所述,不能用实例化类的方式来实例化接口。下面的示例提供了一些类定义的代码和使用它们的代码。
  1. namespace Ch09Ex01
  2. {
  3. public abstract class MyBase
  4. {
  5. }
  6. internal class MyClass : MyBase
  7. {
  8. }
  9. public interface IMyBaseInterface
  10. {
  11. }
  12. public interface IMyBaseInterface2
  13. {
  14. }
  15. internal interface IMyInterface : IMyBaseInterface, IMyBaseInterface2
  16. {
  17. }
  18. interface sealed class MyComplexClass : MyClass, IMyInterface
  19. {
  20. }
  21. class Program
  22. {
  23. MyComplexClass myObj = new MyComplexClass();
  24. Console.WriteLine(myObj.ToString());
  25. Console.ReadKey();
  26. }
  27. }
  示例的说明

  这个项目在下面的继承层次结构中定义了类和接口,如图 9-2 所示。

  这里包含 Program,是因为尽管这个类不是主要类层次结构中的一部分,但是它的定义方式与其他类的定义方式相同。这个类处理的 Main() 方法是应用程序的入口点。

  MyBaseIMyBaseInterface 被定义为公共的,所以可以在其他项目中使用它们。其他类和接口都是内部的,只能在本项目中使用。

图 9-2

  Main() 中的代码调用 MyComplexClass 的一个实例 myObjToString() 方法:

  1. MyComplexClass myObj = new MyComplexClass ();
  2. Console.WriteLine(myObj.ToString());

  这是继承自 System.Object 的一个方法(图中没有显示,为清晰起见,该图省略了这个类的成员),并把对象的类名作为一个字符串返回,该类名用相关的名称空间来限定。

  这个示例没有完成什么具体的工作,但本章后面还要利用这个示例演示几个重要概念和技术。