C#使用class關鍵字來定義類:
class MyClass { // Class members. } |
這段代碼定義了一個類MyClass。定義了一個類后,就可以在項目中能訪問該定義的其他地方對該類進行實例化。在默認情況下,類聲明為內部的,即只有當前項目中的代碼才能訪問它。可以用internal訪問修飾符關鍵字顯式指定,如下所示(但這是不必要的):internal class MyClass { // Class members. } |
另外,還可以指定類是公共的,應可以由其他項目中的代碼來訪問。為此,要使用關鍵字public。
public class MyClass { // Class members. } |
注意:
以這種方式聲明的類不能是私有或受保護的??梢园堰@些聲明類的修飾符用于聲明類成員,詳見第10章。
除了這兩個訪問修飾符關鍵字外,還可以指定類是抽象的(不能實例化,只能繼承,可以有抽象成員)或密封的(sealed,不能繼承)。為此,可以使用兩個互斥的關鍵字abstract 或sealed。所以,抽象類必須用下述方式聲明:
public abstract class MyClass { // Class members, may be abstract. } |
其中MyClass是一個公共抽象類,也可以是內部抽象類。
密封類的聲明如下所示:
public sealed class MyClass { // Class members. } |
與抽象類一樣,密封類也可以是公共或內部的。
還可以在類定義中指定繼承。為此,要在類名的后面加上一個冒號,其后是基類名,例如:
public class MyClass : MyBase { // Class members. } |
注意,在C#的類定義中,只能有一個基類,如果繼承了一個抽象類,就必須實現(xiàn)所繼承的所有抽象成員(除非派生類也是抽象的)。
編譯器不允許派生類的可訪問性比其基類更高。也就是說,內部類可以繼承于一個公共類,但公共類不能繼承于一個內部類。因此,下述代碼是合法的:
public class MyBase { // Class members. } internal class MyClass : MyBase { // Class members. } |
但下述代碼不能編譯:internal class MyBase { // Class members. } public class MyClass : MyBase { // Class members. } |
如果沒有使用基類,則被定義的類就只繼承于基類System.Object(它在C#中的別名是object)。畢竟,在繼承層次結構中,所有類的根都是System.Object,稍后將詳細介紹這個基類。
除了以這種方式指定基類外,還可以在冒號的后面指定支持的接口。如果指定了基類,它必須緊跟在冒號的后面,之后才是指定的接口。如果沒有指定基類,則接口就跟在冒號的后面。必須使用逗號分隔基類名(如果有基類)和接口名。
例如,給MyClass添加一個接口,如下所示:
public class MyClass : IMyInterface { // Class members. } |
所有的接口成員都必須在支持該接口的類中實現(xiàn),但如果不想使用給定的接口成員,就可以提供一個"空"的執(zhí)行方式(沒有函數(shù)代碼)。還可以把接口成員實現(xiàn)為抽象類中的抽象成員。
下面的聲明是無效的,因為基類MyBase不是繼承列表中的第一項:
public class MyClass : IMyInterface, MyBase { // Class members. } |
指定基類和接口的正確方式如下:public class MyClass : MyBase, IMyInterface { // Class members. } |
可以指定多個接口,所以下面的代碼是有效的:
public class MyClass : MyBase, IMyInterface, IMySecondInterface { // Class members. }32 |
表1是類定義中可以使用的訪問修飾符的組合。
表 1
修 飾 符 | 含 義 |
無或internal | 類只能在當前項目中訪問 |
public | 類可以在任何地方訪問 |
abstract 或internal abstract | 類只能在當前項目中訪問,不能實例化,只能繼承 |
public abstract | 類可以在任何地方訪問,不能實例化,只能繼承 |
sealed或internal sealed | 類只能在當前項目中訪問,不能派生,只能實例化 |
public sealed | 類可以在任何地方訪問,不能派生,只能實例化 |
接口的定義
聲明接口的方式與聲明類的方式相似,但使用的關鍵字是interface,而不是class,例如:
interface IMyInterface { // Interface members. } |
訪問修飾符關鍵字public 和 internal的使用方式是相同的,與類一樣,接口也默認定義為內部接口。所以要使接口可以公開訪問,必須使用public關鍵字:public interface IMyInterface { // Interface members. } |
關鍵字abstract 和 sealed不能在接口中使用,因為這兩個修飾符在接口定義中是沒有意義的(它們不包含執(zhí)行代碼,所以不能直接實例化,且必須是可以繼承的)。
接口的繼承也可以用與類繼承的類似方式來指定。主要的區(qū)別是可以使用多個基接口,例如:
public interface IMyInterface : IMyBaseInterface, IMyBaseInterface2 { // Interface members. } |
接口不是類,所以沒有繼承System.Object。但是為了方便,System.Object的成員可以通過接口類型的變量來訪問。如上所述,不能用實例化類的方式來實例化接口。下面的示例提供了一些類定義的代碼和使用它們的代碼。
試試看:定義類
(1) 創(chuàng)建一個新的控制臺應用程序Ch09Ex01。
(2) 修改Program.cs中的代碼,如下所示:
namespace Ch09Ex01 { public abstract class MyBase { } internal class MyClass : MyBase { } public interface IMyBaseInterface { } internal interface IMyBaseInterface2 { } internal interface IMyInterface : IMyBaseInterface, IMyBaseInterface2 { } internal sealed class MyComplexClass : MyClass, IMyInterface { } class Program { static void Main(string[] args) { MyComplexClass myObj = new MyComplexClass(); Console.WriteLine(myObj.ToString ()); Console.ReadKey(); } } } |
(3) 執(zhí)行項目,結果如圖1所示。

圖 1
示例的說明
這個項目在下面的繼承層次結構中定義了類和接口,如圖2所示。
圖 2
這里包含Program,是因為這個類的定義方式與其他類的定義方式相同,而它不是主要類層次結構中的一部分。這個類處理的Main()方法是應用程序的入口點。
MyBase和IMyBaseInterface被定義為公共的,所以它們可以在其他項目中使用。其他類和接口都是內部的,只能在這個項目中使用。
Main()中的代碼調用MyComplexClass的一個實例myObj的ToString()方法:
MyComplexClass myObj = new MyComplexClass(); Console.WriteLine(myObj.ToString()); |
這是繼承自System.Object的一個方法(圖中沒有顯示,因為該圖省略了這個類的成員),并把對象的類名作為一個字符串返回,該類名用所有相關的名稱空間來限定。