第十三章、创建接口和定义抽象类

  接口不包含任何代码或数据:它只规定了从接口继承的类必须提供哪些方法和属性。使用接口,方法的名称/签名可以和方法的具体实现完全隔绝。

  抽象类在许多方面都和接口相似,只是它们可以包含代码和数据。然而,可以将抽象类的某些方法指定为虚方法,指示从抽象类继承的类必须以自己的方式实现这些方法。

  理解接口

  接口指定“有什么”,也就是方法的名称、返回类型和参数。至于具体“如何做”。或者说方法具体如何实现,则不是接口所关心的。接口描述了类提供的功能,但不描述功能如何实现。

  定义接口

  定义接口类似于定义类,只是要用interface关键字而不是class关键字。在接口中,要按照与类或结构中一样的方式声明方法,只是不允许指定任何访问类型。另外,接口中的方法是没有实现的,它们只是声明。实现接口的所有类型都必须提供自己的实现。所有,方法主体被替换成一个分号。如:

  interface IComparable{

  int CompareTo(Object obj);

  }

  Microsoft.NET Framework 文档建议接口名以大写字母I开头。

  接口不包含任何数据:不可以向接口添加字段(私有的也不行)。

  实现接口

  为了实现接口,需要声明类或结构从接口继承,并实现接口指定的全部方法。虽然不能从一个结构派生出另一个结构,但结构是可以实现接口的(从接口“继承”)。

  interface ILandBound

  {

  int NumberLegs();

  }

  calss Horse: ILandBound

  {

  ..........

  public int NumberLegs()   //隐式实现接口

  {

  return 4;

  }

  }

  实现接口时,必须保证每个方法都完全匹配对应的接口方法,具体遵循以下几个规则:

  ①方法名和返回类型完全匹配

  ②所有参数(包括ref和out关键字修饰符)都完全匹配

  ③用于实现接口的所有方法都必须具有public可访问性。但是,如果使用显示接口实现,则不应该为方法添加访问修饰符。

  一个类可以在扩展另一个类的同时实现接口。C#用一种位置记号来加以区分。首先写基类名,再写逗号,最后写接口名。如

  interface ILandBound

  {

  ............

  }

  class Mammal

  {

  .................

  }

  class Horse:Mammal, ILandBound

  {

  .................

  }

  一个接口可以从另一个接口继承,这在技术上称为接口扩展。

  使用多个接口

  一个类最多只能有一个基类,但可以实现不限数量的接口。

  class Horse:Mammal, ILandBound,IGrazable

  {

  .....................

  }

  显示实现接口

  interface ILandBound

  {

  int NumberOfLegs(); //几条腿

  }

  interface IJourney

  {

  int NumberOfLegs();//跑了几站

  }

  class Horse : ILandBound, IJourney

  {

  .......

  int ILandBound. NumberOfLegs()

  {

  return 4;

  }

  int IJourney. NumberOfLegs()

  {

  return 3;

  }

  }

  如果方法是显示接口实现的一部分,就不能为方法指定访问修饰符。

  访问显示实现接口的方法,通过接口引用对象:

  Horse horse = new Horse();

  .......

  IJourney journeyHorse = horse;

  int legInJourney = journeyHorse .NumberOfLegs();

  ILandBound landBoundHorse = horse;

  int legInHorse = landBoundHorse .NumberOfLegs();

  接口的限制

  ①不允许在接口中定义任何字段,包括静态字段。

  ②不允许在接口中定义任何构造器。

  ③不允许在接口中定义任何析构器。析构器包含由于析构(销毁)对象实例的语句。

  ④不允许为任何方法指定访问修饰符

  ⑤不允许在接口中嵌套任何类型(如枚举、结构、类或接口)。

  ⑥虽然一个接口能从另一个接口继承,但不允许从结构或者类中继承一个接口。

  抽象类

  为了明确声明不允许创建某个类的实例,必须将那个类显式声明为抽象类(不能封装,不允许实例化对象),这是用abstract关键字完成的。如:定义一个草食性哺乳动物抽象类

  abstract class GrazingMammal: Mammal,IGrazable

  {

  ........................

  }

  试图实例化一个GrazingMammal对象,代码将无法通过编译。

  抽象方法

  抽象类可以包含抽象方法。抽象方法原则上与虚方法相似,只是它不包含方法主体。派生类必须重写(override)这种方法。抽象方法适合在以下情形下使用:一个方法在抽象类中提供默认实现没有意义,但又需要继承类提供该方法的实现。

   abstract abstract   class GrazingMammal: Mammal,IGrazable

  {

  abstract void DigestGrass();  //抽象方法

  ........................

  }

  密封类

  如果不想一个类作为基类使用,可以使用C#提供的sealed(密封)关键字防止类被用作基类。例如:

  sealed class Horse: GrazingMammal,ILandBound

  {

  ..................

  }

  在密封类中不能声明任何虚方法,另外抽象类不能密封。

  结构隐式密封。永远不能从一个结构派生。

  密封方法

  可用sealed关键字密封继承到的虚方法,阻止当前类的派生类继续重写该方法。只有重写方法才能密封(用sealed override 来修饰方法)。可像下面这样理解interface、virtual、override和sealed关键字

  interface(接口)引入方法名称。

  virtual(虚)是方法的第一个实现,可由派生类重写。

  override(重写)是派生类重写的实现,是方法的第二个实现。

  sealed(密封)是方法的最后一个实现,再下面的派生类不能重写了。

原文地址:https://www.cnblogs.com/linhuide/p/5819875.html