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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© qly2046 中级黑马   /  2014-1-2 11:49  /  1866 人查看  /  9 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 qly2046 于 2014-1-2 22:10 编辑

看完关于接口的介绍,感觉接口很强大,但是我仍感觉云里雾里。
希望高手能简单易懂的讲解一下,让我不再疑惑?例子也要简单一点。

评分

参与人数 1技术分 +1 收起 理由
陈福军 + 1

查看全部评分

9 个回复

倒序浏览
我来讲一下自己对接口的通俗理解吧,
Java中的接口是一系列方法的声明,在其他的类中可以来对其进行实现(implements)
也就是在声明了接口后,
在实现其接口时就需要按照接口的声明来实现
例如参数类型,方法名等,都必须严格按照接口定义来写。

评分

参与人数 1技术分 +1 收起 理由
陈福军 + 1

查看全部评分

回复 使用道具 举报
jibenwujie 发表于 2014-1-2 12:01
我来讲一下自己对接口的通俗理解吧,
Java中的接口是一系列方法的声明,在其他的类中可以来对其进行实现(im ...

邻家姐姐,你举个浅显易懂的例子呗?:#

点评

比如在一个项目中的dao层和它的实现类。 一般会在dao层中定义好接口,再对其进行实现  发表于 2014-1-2 14:48
回复 使用道具 举报
接口只包含方法、属性、事件或索引器的签名。成员的实现是在实现接口的类或结构中完成的,如下面的示例所示:

interface ISampleInterface
{
    void SampleMethod();
}

class ImplementationClass : ISampleInterface
{
    // Explicit interface member implementation:
    void ISampleInterface.SampleMethod()
    {
        // Method implementation.
    }

    static void Main()
    {
        // Declare an interface instance.
        ISampleInterface obj = new ImplementationClass();

        // Call the member.
        obj.SampleMethod();
    }
}
接口可以是命名空间或类的成员,并且可以包含下列成员的签名:
方法
属性
索引器
事件
一个接口可从一个或多个基接口继承。
当基类型列表包含基类和接口时,基类必须是列表中的第一项。
实现接口的类可以显式实现该接口的成员。显式实现的成员不能通过类实例访问,而只能通过接口实例访问。
有关显式接口实现的更多详细信息和代码示例,请参见显式接口实现(C# 编程指南)。
下面的示例演示了接口实现。在此示例中,接口包含属性声明,类包含实现。


interface IPoint
{
   // Property signatures:
   int x
   {
      get;
      set;
   }

   int y
   {
      get;
      set;
   }
}

class Point : IPoint
{
   // Fields:
   private int _x;
   private int _y;

   // Constructor:
   public Point(int x, int y)
   {
      _x = x;
      _y = y;
   }

   // Property implementation:
   public int x
   {
      get
      {
         return _x;
      }

      set
      {
         _x = value;
      }
   }

   public int y
   {
      get
      {
         return _y;
      }
      set
      {
         _y = value;
      }
   }
}

class MainClass
{
   static void PrintPoint(IPoint p)
   {
      Console.WriteLine("x={0}, y={1}", p.x, p.y);
   }

   static void Main()
   {
      Point p = new Point(2, 3);
      Console.Write("My Point: ");
      PrintPoint(p);
   }
}
// Output: My Point: x=2, y=3

评分

参与人数 1技术分 +1 收起 理由
陈福军 + 1

查看全部评分

回复 使用道具 举报
1.
--接口描述的是可属于任何类或结构的一组相关功能。
--接口没有字段,没有构造函数(由方法、属性、事件、索引器或这四种成员类型的任意组合构成)
--接口没有实现
--不能直接实例化接口
--接口可以继承其他多个接口,类和结构可从多个接口继承。
--若要实现接口成员,类中的对应成员必须是公共的、非静态的,并且与接口成员具有相同的名称和签名。
--继承接口的任何非抽象类型都必须实现接口的所有成员
--类或结构继承接口与类继承基类或结构的区别:可继承多个接口。仅继承方法名称和签名
  1. interface IEquatable<Car>
  2. {
  3.     bool Equals(Car obj);
  4. }
  5. public class Car : IEquatable<Car>
  6. {
  7.     public string Make {get; set;}
  8.     public string Model { get; set; }
  9.     public string Year { get; set; }

  10.     // Implementation of IEquatable<T> interface
  11. <font color="#ff0000">    public</font> bool Equals(Car car)
  12.     {
  13.         if (this.Make == car.Make &&
  14.             this.Model == car.Model &&
  15.             this.Year == car.Year)
  16.         {
  17.             return true;
  18.         }
  19.         else
  20.             return false;
  21.     }
  22. }
  23. class test
  24. {
  25.        static void Main()
  26.        {
  27.               Car car1=new Car();
  28.               Car car2=new Car();
  29.               if(car1.Equals(car2))
  30.               {
  31.                      System.Console.WriteLine("equal");
  32.               }
  33.               else
  34.               {
  35.                      System.Console.WriteLine("not equal");
  36.               }
  37.        }
  38. }
  39. /*
  40. equal
  41. */
复制代码


2.
类的属性和索引器可以为接口上定义的属性或索引器定义额外的访问器。例如,接口可以声明一个带有 get 访问器的属性,而实现该接口的类可以声明同时带有 get 和 set 访问器的同一属性。但是,如果属性或索引器使用显式实现,则访问器必须匹配。
3.
类可以通过其继承的基类或接口多次继承某个接口。在这种情况下,如果将该接口声明为新类的一部分,则该类只能实现该接口一次。如果没有将继承的接口声明为新类的一部分,其实现将由声明它的基类提供。基类可以使用虚拟成员实现接口成员;在这种情况下,继承接口的类可通过重写虚拟成员来更改接口行为
4.
语法分析:
情况一:两个接口包含具有相同签名的成员
  1. interface IControl
  2. {
  3.     void Paint();
  4. }
  5. interface ISurface
  6. {
  7.     void Paint();
  8. }
复制代码
结果:在类中实现该成员将导致两个接口都使用该成员作为它们的实现
  1. interface IControl
  2. {
  3.     void Paint();
  4. }
  5. interface ISurface
  6. {
  7.     void Paint();
  8. }
  9. class SampleClass : IControl, ISurface
  10. {
  11.     // Both ISurface.Paint and IControl.Paint call this method.
  12. <font color="#ff0000">    public</font> void Paint()
  13.     {
  14.     }
  15. }
复制代码
情况二:两个接口分别声明具有相同名称的不同成员(如属性和方法)
  1. interface ILeft
  2. {
  3.     int P { get;}
  4. }
  5. interface IRight
  6. {
  7.     int P();
  8. }
复制代码
结果:在类中实现该成员将导致编译器错误
解决办法:可以显式地实现接口成员(即创建一个仅通过该接口调用并且特定于该接口的类成员)
针对情况一:(方法有多种)
  1. public class SampleClass : IControl, ISurface
  2. {
  3.     void IControl.Paint()//没有public
  4.     {
  5.         System.Console.WriteLine("IControl.Paint");
  6.     }
  7.     void ISurface.Paint()//没有public
  8.     {
  9.         System.Console.WriteLine("ISurface.Paint");
  10.     }
  11. }
复制代码
类成员 IControl.Paint 只能通过 IControl 接口使用,ISurface.Paint 只能通过 ISurface 使用。两个方法实现都是分离的,都不可以直接在类中使用。
  1. SampleClass obj = new SampleClass();
  2. //obj.Paint();  // Compiler error.
  3. IControl c = (IControl)obj;
  4. c.Paint();  // Calls IControl.Paint on SampleClass.
  5. ISurface s = (ISurface)obj;
  6. s.Paint(); // Calls ISurface.Paint on SampleClass.
复制代码

针对情况二:为了同时实现两个接口,类必须对属性 P 和/或方法 P 使用显式实现(方法有多种)
  1. class Middle : ILeft, IRight
  2. {
  3. <font color="#ff0000">    public</font> int P() { return 0; }
  4. <font color="#ff0000">    int ILeft.P</font> { get { return 0; } }//没有public
  5. }
复制代码

使用办法与上面类似
实际应用:
例:同时以公制单位和英制单位显示框的尺寸。Box 类实现 IEnglishDimensions 和 IMetricDimensions 两个接口,它们表示不同的度量系统。两个接口有相同的成员名称 Length 和 Width。
  1. // Declare the English units interface:
  2. interface IEnglishDimensions
  3. {
  4.     float Length();
  5.     float Width();
  6. }

  7. // Declare the metric units interface:
  8. interface IMetricDimensions
  9. {
  10.     float Length();
  11.     float Width();
  12. }

  13. // Declare the Box class that implements the two interfaces:
  14. // IEnglishDimensions and IMetricDimensions:
  15. class Box : IEnglishDimensions, IMetricDimensions
  16. {
  17.     float lengthInches;
  18.     float widthInches;

  19.     public Box(float length, float width)
  20.     {
  21.         lengthInches = length;
  22.         widthInches = width;
  23.     }

  24.     // Explicitly implement the members of IEnglishDimensions:
  25.     float IEnglishDimensions.Length()
  26.     {
  27.         return lengthInches;
  28.     }

  29.     float IEnglishDimensions.Width()
  30.     {
  31.         return widthInches;
  32.     }

  33.     // Explicitly implement the members of IMetricDimensions:
  34.     float IMetricDimensions.Length()
  35.     {
  36.         return lengthInches * 2.54f;
  37.     }

  38.     float IMetricDimensions.Width()
  39.     {
  40.         return widthInches * 2.54f;
  41.     }

  42.     static void Main()
  43.     {
  44.         // Declare a class instance box1:
  45.         Box box1 = new Box(30.0f, 20.0f);

  46.         // Declare an instance of the English units interface:
  47.         IEnglishDimensions eDimensions = (IEnglishDimensions)box1;

  48.         // Declare an instance of the metric units interface:
  49.         IMetricDimensions mDimensions = (IMetricDimensions)box1;

  50.         // Print dimensions in English units:
  51.         System.Console.WriteLine("Length(in): {0}", <font color="#ff0000">eDimensions.Length()</font>);
  52.         System.Console.WriteLine("Width (in): {0}", <font color="#ff0000">eDimensions.Width()</font>);

  53.         // Print dimensions in metric units:
  54.         System.Console.WriteLine("Length(cm): {0}", <font color="#ff0000">mDimensions.Length()</font>);
  55.         System.Console.WriteLine("Width (cm): {0}", <font color="#ff0000">mDimensions.Width()</font>);
  56.     }
  57. }
  58. /* Output:
  59.     Length(in): 30
  60.     Width (in): 20
  61.     Length(cm): 76.2
  62.     Width (cm): 50.8
  63. */
复制代码


都只能通过接口访问,不能直接在类中使用
如果希望默认度量采用英制单位,则正常实现 Length 和 Width 这两个方法,并从 IMetricDimensions 接口显式实现 Length 和 Width 方法:
  1. // Normal implementation:
  2. <font color="#ff0000">public</font> float Length()
  3. {
  4.     return lengthInches;
  5. }
  6. <font color="#ff0000">public</font> float Width()
  7. {
  8.     return widthInches;
  9. }

  10. // Explicit implementation:
  11. float IMetricDimensions.Length()
  12. {
  13.     return lengthInches * 2.54f;
  14. }
  15. float IMetricDimensions.Width()
  16. {
  17.     return widthInches * 2.54f;
  18. }
复制代码
这种情况下,可以从类实例访问英制单位,而从接口实例访问公制单位:
  1. public static void Test()
  2. {
  3.     Box box1 = new Box(30.0f, 20.0f);
  4.     IMetricDimensions mDimensions = (IMetricDimensions)box1;

  5.     System.Console.WriteLine("Length(in): {0}", <font color="#ff0000">box1.Length()</font>);
  6.     System.Console.WriteLine("Width (in): {0}", <font color="#ff0000">box1.Width()</font>);
  7.     System.Console.WriteLine("Length(cm): {0}", mDimensions.Length());
  8.     System.Console.WriteLine("Width (cm): {0}", mDimensions.Width());
  9. }
复制代码


评分

参与人数 1技术分 +2 收起 理由
V_John + 2

查看全部评分

回复 使用道具 举报
简介

1. [1]接口是一个引用类型,通过接口可以实现多重继承。
2. C#中接口有new、public、protected、internal、private等修饰符。
3. 接口中只能声明抽象成员(所以不能直接对接口进行实例化(即不能使用new操作符声明一个接口的实例对 象)),而不能声明共有的域或者私有的成员变量。
4. 接口声明不包括数据成员,只能包含方法、属性、事件、索引等成员。
5. 接口名称一般都以“I”作为首字母(当然不这样声明也可以),这也是接口和类的一个区别之一。[2]
6. 接口成员的访问级别是默认的(默认为public),所以在声明时不能再为接口成员指定除public外的任何访问修饰符,否则 编译器会报错。
7. 接口成员不能有static、abstract、override、virtual修饰符,使用new修饰符不会报错,但会给出警告说不需要关键字new。
8. 在声明接口成员的时候,不准为接口成员编写具体的可执行代码,也就是说,只要在对接口进行声明时指明接口的成员名称和参数就可以了。
9. 接口一旦被继承,子类需要把接口中所有成员实例化(通过具体的可执行代码实现接口抽象成员的操作)。
2C#接口

C#接口代码学习
c#代码参考
接口(C# 参考)
接口包含的成员只有方法,属性,索引器(有参属性),事件四种成员。方法的实现是在实现接口的类中完成的,如下面的示例所示:
interface ISampleInterface
{
void SampleMethod();
}
class ImplementationClass : ISampleInterface
{
// Explicit interface member implementation:
void ISampleInterface.SampleMethod()
{
// Method implementation.
}
static void Main()
{
// Declare an interface instance.
ISampleInterface obj = new ImplementationClass();
// Call the member.
obj.SampleMethod();
}
}
---------------------------------------------------------------------------------------------------------
备注:
接口可以是命名空间或类的成员,并且可以包含下列成员的签名:
·方法  ·属性  ·索引器 ·事件 
3事件

一个接口可从一个或多个基接口继承。
当基类型列表包含基类和接口时,基类必须是列表中的第一项。
实现接口的类可以显式实现该接口的成员。显式实现的成员不能通过类实例访问,而只能通过接口实例访问。
---------------------------------------------------------------------------------------------------------
4示例

下面的示例演示了接口实现。在此例中,接口 IPoint 包含属性声明,后者负责设置和获取字段的值。Point 类包含属性实现。
using System;
interface IPoint
{
int x { get ; set ; } //声明属性成员
int y { get ; set ; }
}
class Point : IPoint
{
private int _X; //声明成员变量
private int _Y;
public Point(int x, int y) { _X = x ; _Y = y ; } //定义构造函数
public int x //定义属性成员
{
get { return _X ; }
set { _X = value ; }
}
public int y //定义属性成员
{
get { return _Y ; }
set { _Y = y ; }
}
}
class Test
{
private static void PrintPoint(IPoint p) //定义输出函数
{
Console.WriteLine("x={0},y={1}", p.x, p.y);
}
public static void Main()
{
IPoint p = new Point(2, 3);
Console.Write("My Point is:");
PrintPoint(p);
}
}
输出结果:
My Point is: x=2, y=3

评分

参与人数 1技术分 +1 收起 理由
陈福军 + 1

查看全部评分

回复 使用道具 举报
说准确点,接口中只能够定义方法,但是由于属性,索引内部还是由方法组成,故也可以定义; 接口只是说明了能够做什么,有什么能力(相当于C语言中函数的声明),而不能对方法有具体的实现,接口中的方法的具体实现是在继承(接口一般是说实现接口,此处主要是和前面进行区别)这个接口的子类中实现;你可以去看看ADO中操作数据库的类和方法,在类后面有I开头的父类按F12,慢慢研究一下就知道了

评分

参与人数 1技术分 +1 收起 理由
V_John + 1

查看全部评分

回复 使用道具 举报
接口在实际应用中,为派生接口和派生类提供了一个通用的方法集,而这个方法集的作用就是约束实现者能做这些事,接口实现和类继承的关系不一样,书上曾说过接口一般充当can-do的角色,而继承充当is-a的角色

评分

参与人数 1技术分 +1 收起 理由
陈福军 + 1

查看全部评分

回复 使用道具 举报
说一下我的理解吧:对于类我们一般为了实现多重继承,而C#中却没有多重继承,为了满足我们的需求。
我们在创建类之前一般定义接口,目的为了实现多重继承,方法的格式统一。再定义实现接口的类。
这里说一下接口和类的区别:
1、接口中的成员变量默认是公共的(public),而类中的成员变量是私有的(private)。因此接口中不允许有成员上的访问修饰符
2、可以有任何的私有成员(方法、属性、索引器、事件),但不能有字段
3、不能在接口中实现接口成员(方法只能有方法头,不能有方法体)
4、接口中的任何成员必须在子类中都实现
eg:
class Person:IPerson
    {
        public string Name { set; get; }//必须要实现所有的接口成员,不能去掉public ,去掉了就成为私有字段,
        //不再是接口中信息的实现了
        public  int Age { set; get; }
        public  void SayHellow()
        {
            Console.WriteLine("huanyingnide daolai ");
        }
    }


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