zoukankan      html  css  js  c++  java
  • 第十三章、创建接口和定义抽象类

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

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

      理解接口

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

      定义接口

      定义接口类似于定义类,只是要用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(密封)是方法的最后一个实现,再下面的派生类不能重写了。

  • 相关阅读:
    Mac OS X上安装 Ruby运行环境
    MAC 命令行工具(Command Line Tools)安装
    如何快速正确的安装 Ruby, Rails 运行环境
    安裝 Rails 開發環境
    用模块化编程
    阅读技术书籍
    NHibernate构建一个ASP.NET MVC应用程序
    SQL注入
    Redis
    Code digest
  • 原文地址:https://www.cnblogs.com/linhuide/p/5819875.html
Copyright © 2011-2022 走看看