在實際專案中,當我們設計一個父類別時,常常會遇到這個類別不能確定它的具體執行流程的。例如我設計一個檔案類別:
public class AFile { private string name = string.Empty; private string path = string.Empty; private FileType type = FileType.IsUnknown; public string Name { get { return name; } } public string Path { get { return path; } } public FileType Type { get { return type; } } public AFile(string name, string path, FileType type) { this.name = name; this.path = path; this.type = type; } public void Copy(string destPath) { //不知道怎么写,因为可能是文件还可能是文件夹,如果是压缩的还要解压 } } public enum FileType { IsUnknown = 0,//类型不明 IsFile = 1,//文件 IsDirectory =2,//文件夹 IsCompression//压缩的 }
這是一個父類,它的copy方法,該怎麼寫呢?因為文件有四種狀態甚至後來根據需要還可能再加,針對不同的文件類型,拷貝方法是不一樣的,而且根據項目需要還可能針對某種文件做一些特殊處理。這樣再設計這個父類別時就不能對copy方法寫程式碼,只需要誰繼承它誰就重寫這個方法,根據需要寫不同的執行程式碼。
這樣,一個類別具有某個方法,但是該方法沒有具體執行過程,這樣的方法稱之為「抽象方法」。
上面的AFile類別中Copy方法就叫抽象方法,但是隨之有一個問題,如果實例化了這個AFile類,Copy方法也就是這個物件的行為了,但實際上Copy方法還不確定。這樣不符合客觀事物法則。因此,這個類別是不能被實例化的,也就是說當類別中有抽象方法時,這個類別不能被實例化,這樣的類別就稱為「抽象類別」。抽像不能被實例化,但它還是類別。抽象類別和抽象方法用abstract關鍵字修飾。
可以看到,抽象類別中就存在了兩種方法:抽象方法和非抽象方法。
非抽象方法,抽象類別被繼承,子類別有非抽象方法,可以直接使用,也可以重寫覆寫。
抽象類,必須覆寫重寫。
修改上述的檔案類別:
using System; using System.Collections.Generic; using System.Text; using System.IO; namespace YYS.CSharpStudy.MainConsole { public abstract class AFile { private string name = string.Empty; private string path = string.Empty; private FileType type = FileType.IsUnknown; public string Name { get { return name; } } public string AFilePath { get { return path; } } public FileType Type { get { return type; } } public AFile(string name, string path, FileType type) { this.name = name; this.path = path; this.type = type; } public abstract void Copy(string destPath); } public enum FileType { IsUnknown = 0,//类型不明 IsFile = 1,//文件 IsDirectory =2,//文件夹 IsCompression//压缩的 } /// <summary> /// 文件类 /// </summary> public class FileInfo : AFile { public FileInfo(string name, string path, FileType type) : base(name, path, type) { } /// <summary> /// 文件的拷贝方法 /// </summary> public override void Copy(string destPath) { if (string.IsNullOrEmpty(destPath)) { string sourcePath = this.AFilePath + this.Name; //此时name是文件名,带有后缀名,加起来是文件路径 destPath += this.Name; if (File.Exists(sourcePath)) { File.Copy(sourcePath, destPath, true); } } } } /// <summary> /// 文件夹类 /// </summary> public class FileDirectoryInfo : AFile { public FileDirectoryInfo(string name, string path, FileType type) : base(name, path, type) { } /// <summary> /// 文件的拷贝方法 /// </summary> public override void Copy(string destPath) { if (string.IsNullOrEmpty(destPath)) { string sourcePath = this.AFilePath + this.Name; //此时文件名是文件夹名,加起来是文件夹路径 destPath += this.Name; if (Directory.Exists(sourcePath)) { CopyDirectory(sourcePath, destPath); } } } /// <summary> /// 拷贝文件夹的方法 /// </summary> private void CopyDirectory(string sourcePath, string destPath) { try { if (!Directory.Exists(destPath)) { Directory.CreateDirectory(destPath); } DirectoryInfo directoryInfo = new DirectoryInfo(sourcePath); foreach (FileSystemInfo fileInfo in directoryInfo.GetFileSystemInfos()) { string subFileOrDirectoryName = Path.Combine(destPath, fileInfo.Name); if (fileInfo is DirectoryInfo) { this.CopyDirectory(fileInfo.FullName, subFileOrDirectoryName); } else { if (File.Exists(sourcePath)) { File.Copy(sourcePath, destPath, true); } } } } catch{} } } }
這樣,就完成了抽象類別的繼承並實現。但是如果子類別繼承了抽象類,但是並沒有實作抽象方法,那麼這個子類別也會作為一個抽象類別存在。有抽象方法的類別叫做抽象類,對於有些情況,沒有抽象方法的類,也可以使用abstract關鍵字定義為抽象類,這樣表示該類別不能被抽象,必須被繼承。
以上是C#基礎知識整理:基礎知識(6) 抽象類別與抽象方法 的內容,更多相關內容請關注PHP中文網(www.php.cn)!