C#接口日志(基础整理)

     在学习的过程中遇到困惑,不理解? 那就先把它记住,狠狠地记住,就像万有引力,它是那样的,程序语言也是,它就是这样设计的,记清楚也就知道了。

  接口标志类的类别(type of class)把不同类型的类归于不同的接口,可以更好的管理他们。OO的精髓是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。(cowboy的名言是“抽象就是抽去像的部分”,看似调侃,实乃至理)。

  接口简单理解就是一种约定,使得实现接口的类或结构在形式上保持一致,使程序更加清晰和条理化。

   就好比银行卡的银联,不管工商银行,农业银行都有银联的标志,你如果拿了个没有银联的卡多不方便,这个银联就是接口,只要你继承它的接口,实现了接口中定义的功能,走到哪人家都认。

      接口还能多继承,就像人不是每一个人的能力都一样,比如咸蛋超人,和普通人有啥区别?会飞是不,普通人会吗? 这就是一个特殊能力,你可以利用到接口了,普通人的类继承一个会飞的接口,并实现飞的方法,那么这个人就是咸蛋超人了。那么多继承不就是多继承几个特殊能力接口,咸蛋超人就能成百变金刚了。

  C#中接口的用法:定义接口,里面包含方法,但没有方法具体实现的代码,然后在继承该接口的类里面“具体实现”接口的所有方法。

  接口可由方法、属性、事件、索引器或这四种成员类型的任意组合构成。 接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型。 它不能包含静态成员。 接口成员是自动公开的,且不能包含任何访问修饰符。

   类或结构实现接口时,该类或结构将为该接口定义的所有成员提供实现。 接口本身不提供类或结构能够以继承基类功能的方式继承的任何功能。 但是,如果基类实现接口,派生类将继承该实现。 派生的类被认为是隐式地实现接口。

  类和结构按照类继承基类或结构的类似方式实现接口,但有两个例外:

  • 类或结构可实现多个接口。

  • 类或结构实现接口时,仅接收方法名称和签名,因为接口本身不包含实现,如下面的示例所示。

接口描述的是可属于任何结构的一组相关功能。 接口使用 interface 关键字进行定义,一般我们用一个大写的“I”作为开头来命名:

   public interface IBark
   {
       void Bark();
   }
//再定义一个类,继承于IBark,并且必需实现其中的Bark()方法 public class Dog : IBark { public Dog(){ } public void Bark() { Console.WriteLine("汪汪"); } } //然后,声明Dog的一个实例,并调用Bark()方法 Dog 旺财 = new Dog(); 旺财.Bark();

  试想一样,若是想调用Bark()方法,只需要在Dog()中声明这样的一个方法不就行了吗,干什么还要用接口呢.因为接口中并没有Bark()具体实现.真的实现还是要在Dog()中.那么使用接口不是多此一举吗?
  还有人是这样说的:从接口的定义方面来说,接口其实就是类和类之间的一种协定,一种约束.还拿上面的例子来说.所有继承了IBark接口的类中必需实现Bark()方法.那么从用户(使用类的用户)的角度来说,如果他知道了某个类是继承于IBark接口,那么他就可以放心大胆的调用Bark()方法,而不用管Bark()方法具体是如何实现的.比如,我们另外写了一个类.

      public class Cat:IBark
       {
          public Cat()
          {}
          public void Bark()
          {
             Consol.WriteLine("喵喵");
          }
       }

  当用户用到Cat类或是Dog类的时候,知道他们继承于IBark,那么不用管类里的具体实现,而就可以直接调用Bark()方法,因为这两个类中肯定有关于Bark()方法的具体实现.

显式接口实现

  如果实现两个接口,并且这两个接口包含具有相同签名的成员(正常情况下没人会这样做,这里只做举例来说明情况),那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。 例如:

interface IControl
{
    void Paint();
}
interface ISurface
{
    void Paint();
}
class SampleClass : IControl, ISurface
{
    // Both ISurface.Paint and IControl.Paint call this method.
    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; } }
}

 另外:显式实现的接口成员不能从实例访问。

interface IDimensions
{
    float getLength();
    float getWidth();
}

class Box : IDimensions
{
    float lengthInches;
    float widthInches;

    Box(float length, float width)
    {
        lengthInches = length;
        widthInches = width;
    }
    // Explicit interface member implementation: 
    float IDimensions.getLength()
    {
        return lengthInches;
    }
    // Explicit interface member implementation:
    float IDimensions.getWidth()
    {
        return widthInches;
    }

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

        // Declare an interface instance dimensions:
        IDimensions dimensions = (IDimensions)box1;
//System.Console.WriteLine("Length: {0}", box1.getLength());
        //System.Console.WriteLine("Width: {0}", box1.getWidth());

        System.Console.WriteLine("Length: {0}", dimensions.getLength());
        System.Console.WriteLine("Width: {0}", dimensions.getWidth());
    }
}
/* Output:
    Length: 30
    Width: 20
*/

  请注意 Main 方法中下列代码行被注释掉,因为它们将产生编译错误。

//System.Console.WriteLine("Length: {0}", box1.getLength());
//System.Console.WriteLine("Width: {0}", box1.getWidth());

  还请注意,Main 方法中的下列代码行成功输出框的尺寸,因为这些方法是从接口实例调用的:

System.Console.WriteLine("Length: {0}", dimensions.getLength());
System.Console.WriteLine("Width: {0}", dimensions.getWidth());

 

      以上内容整理于互联网,旨在给予初学者一种易于理解的学习方式,疏漏之处,敬请谅解。

  如果,您认为阅读这篇文章对你有帮助,点击一下左下角的[推荐]

  如果,你想了解我的动态,点击一下左下角的[关注我]

  因为,你们的支持增添我学习的动力,谢谢。

posted @ 2013-06-01 17:54  花落红尘  阅读(2217)  评论(3编辑  收藏  举报