在实际项目中,当我们设计一个父类时,经常会遇到这个类不能确定它的具体执行流程的。比如我设计一个文件类:

  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关键字定义为抽象类,这样表明该类不能被抽象,必须被继承。