実際のプロジェクトでは、親クラスを設計する際に、クラスが具体的な実行プロセスを決定できないことがよくあります。たとえば、ファイル クラスを設計します。
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 メソッドをどのように記述すればよいでしょうか?ファイルは 4 つの状態で存在し、必要に応じて後で追加できるため、コピー方法はファイルの種類によって異なり、プロジェクトのニーズに応じて特定のファイルに対して特別な処理が実行される場合があります。このように、この親クラスを再設計する場合、コピー メソッドのコードを記述することはできません。このメソッドを継承した人だけが、このメソッドをオーバーライドして、必要に応じて別の実行コードを記述することができます。
このように、クラスには特定のメソッドがありますが、そのメソッドには具体的な実行処理が存在しません。このようなメソッドを「抽象メソッド」と呼びます。
上記の AFile クラスの Copy メソッドは抽象メソッドと呼ばれていますが、問題があります。 AFile クラスがインスタンス化されると、Copy メソッドがこのオブジェクトの動作になりますが、実際には Copy メソッドはまだわかりません。これは物事の客観的な法則と矛盾します。したがって、このクラスはインスタンス化できません。つまり、クラス内に抽象メソッドが存在する場合、このクラスはインスタンス化できません。そのようなクラスを「抽象クラス」と呼びます。 Abstract はインスタンス化できませんが、クラスであることに変わりはありません。抽象クラスと抽象メソッドは、abstract キーワードを使用して変更されます。
ご覧のとおり、抽象クラスには、抽象メソッドと非抽象メソッドという 2 つのメソッドがあります。
非抽象メソッド、抽象クラスは継承され、サブクラスには直接使用またはオーバーライドできる非抽象メソッドがあります。
抽象クラスはオーバーライドして書き直す必要があります。
上記のファイルクラスを変更します:
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 中国語 Web サイト (www.php.cn) に注目してください。