A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 于振发 中级黑马   /  2013-9-26 22:49  /  2474 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 于振发 于 2013-9-27 08:56 编辑

使用时有什么需要注意的吗?如何选择是定义一个“完全抽象”
的抽象类,还是接口?什么是接口的“显式实现”?为什么说它很重要?
多谢各位热心解答!

评分

参与人数 1技术分 +1 收起 理由
茹化肖 + 1

查看全部评分

3 个回复

倒序浏览
资料来源于MSDN

抽象类不能实例化。
抽象类的用途是提供多个派生类可共享的基类的公共定义。
抽象类也可以定义抽象方法。
抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块。
抽象类的派生类必须实现所有抽象方法。
抽象类只能单继承


接口类似于抽象基类:实现接口的任何非抽象类型都必须实现接口的所有成员。
不能直接实例化接口。
接口可以包含事件、索引器、方法和属性。
接口不包含方法的实现。
类和结构可继承多个接口。
接口自身可从多个接口继承。


显式接口实现:
如果 类实现两个接口,并且这两个接口包含具有相同签名的成员,那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。
例如:interface IControl
  {
      void Paint();
  }
  interface ISurface
  {
      void Paint();
  }
  class SampleClass : IControl, ISurface
  {
      public void Paint()
      {
      }
  }


然而,如果两个 接口成员执行不同的函数,那么这可能会导致其中一个接口的实现不正确或两个接口的实现都不正确。
可以显式地实现接口成员 -- 即创建一个仅通过该接口调用并且特定于该接口的类成员。
这是使用接口名称和一个句点命名该类成员来实现的。
例如:
public class SampleClass : IControl, ISurface
  {
      void IControl.Paint()
      {
          System.Console.WriteLine("IControl.Paint");
      }
      void ISurface.Paint()
      {
          System.Console.WriteLine("ISurface.Paint");
      }
  }
类成员 IControl.Paint 只能通过 IControl 接口使用, ISurface.Paint 只能通过 ISurface 使用。
两个方法实现都是分离的,都不可以直接在类中使用。
例如:
SampleClass obj = new SampleClass();
  //obj.Paint();  // Compiler error.
   
  IControl c = (IControl)obj;
  c.Paint();  // Calls IControl.Paint on SampleClass.
  
  ISurface s = (ISurface)obj;
  s.Paint(); // Calls ISurface.Paint on SampleClass.
显式实现还用于解决两个接口分别声明具有相同名称的不同成员(如属性和方法)的情况:
interface ILeft
  {
      int P { get;}
  }
  interface IRight
  {
      int P();
  }
为了同时实现两个接口,类必须对属性 P 和/或方法 P 使用显式实现以避免编译器错误。
例如:
class Middle : ILeft, IRight
  {
      public int P() { return 0; }
      int ILeft.P { get { return 0; } }
  }

评分

参与人数 1技术分 +1 收起 理由
茹化肖 + 1

查看全部评分

回复 使用道具 举报
接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。

第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
第二点. 接口可以继承,抽象类不行
第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
第四点. 接口中基本数据类型为static 而抽类象不是的。

当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

接口可以实现也可以继承,抽象类不行

抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的  

所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。
回复 使用道具 举报
抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。

接口:接口是引用类型的,类似于类,和抽象类的相似之处有三点:
1、不能实例化;
2、包含未实现的方法声明;
3、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);
接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。

显式实现接口,C#没有提供任何语法,来在派生类中调用基类中显式实现的接口成员,只有通过接口来访问类中的方法;显式实现接口,可以帮助我们在对象级别隐藏高级成员。但是,不要把显式实现当做安全壁垒。只要把实例强制转换为接口,任何代码都可以调用此类的方法。

何时使用显式接口实现
1 接口多继承,引起命名空间冲突。
2 当需要在开发过程中定义一些只供内部使用的接口时。
3 类型已经有了一个方法,该方法与接口方法的名字和参数相同,但返回类型不同。
4 如果希望接口成员只能通过该接口来调用。例如ICollection<T>.IsReadonly的主要目的是为了让数据绑定基础设施通过ICollection<T>接口来访问。在实现该接口类型时,几乎不会直接访问该方法。因此,IList<T>显式地实现了该接口成员。
5 模拟变体(variance)。(在被覆盖的成员中改变参数或返回值的类型。)例如,为了创建强类型集合,IList的实现通常会显式地实现(隐藏)弱类型成员,并增加强类型的公有成员,以改变参数和返回值的类型

厄这个题好面熟,好像在一个博客里看到说这题是面试题哦、、呵呵

评分

参与人数 1技术分 +1 收起 理由
茹化肖 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马