第七章 接口

来源:互联网 发布:msoffice2016 for mac 编辑:程序博客网 时间:2024/06/09 16:41

为什么使用接口?什么情况下使用接口?来看看下面这个例子:

目前有许多文件的压缩格式,包括:.zip、.rar、.cab、.tar等等。假如每种压缩格式都创建一个类,那么每个压缩实现都会有不同的方法签名,无法提供标准的调用规范。虽然方法可以在基类声明,并在子类实现,但是这样会用掉唯一的基类机会(C#只支持单继承)。而且不同的压缩没有通用的代码,这也使得基类变的没有意义。

所以,在这种情况下,不是共享一个基类,而是共享一个接口。基类一般声明子类需要的共享资源,而接口做某一类功能声明。

注意:基类允许共享签名,也允许共享实现,而接口只共享签名,不共享实现。

1、定义接口

  • 接口中不包含实现部分,只包含声明部分。接口中不能声明字段,只能是方法,或属性,而属性不能有实现部分
  • 接口所有的成员都是公有的,C#不允许为接口成员使用访问修饰符。
  • 一旦类声明实现接口,则该类必须实现接口的所有成员。抽象类允许提供接口成员的抽象实现。
  • 接口不能被实例化,不能通过new创建接口。只有实例化实现接口的类型,才能使用接口的实例
  • 接口的重要目的是多态性,所以接口的成员不能包括静态成员
  • 显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问
  • 隐式实现该接口的成员时,实现的成员可以通过类实例访问,也可以通过接口实例访问,但实现的接口必须为公有的

interface IFileCompression

{

    void Compress(string targetFileName, string[] fileName);

    void Uncompress(string compressedFileName, string expandDirectoryName);

}


2、接口的实现

2.1 显式实现接口成员

2.1.1 显式接口声明

显式接口方法的声明,需要在实现接口方法时,使用接口方法的完全限定名,即“接口名.方法”。

interface IPut()

{

    void PutName();

}

class A : IPut()

{

    public void IPut.PutName()

    {

        ... ...

    }

}

2.1.2 显式接口调用

调用显式接口的方法只能通过接口本身调用,所以,必须将实例转换为接口,或将实现接口的类的实例赋值给接口实例,然后再调用显式接口方法。

A a = new A();

((IPut)a).PutName();

 2.2

2、接口实现多态性

接口是实现多态的一种重要的手段。实现同一接口的不同类,可以将实例赋值给接口的实例,当使用接口实例调用接口声明的方法时,则根据不同的类实例,调用不同的实现。

interface IPut()

{

    void PutName();

}

class A : IPut()

{

    public void PutName()

    {

        System.Console.WriteLine("A类");

    }

}

class B : IPut()

{

    public void PutName()

    {

        System.Console.WriteLine("B类");

    }

}

void main()

{

    IPut ip = new A();

    ip.PutName();

    ip = new B();

    ip.PutName();

}

上例中,类A和类B都继承并实现了接口IPut。在main函数中,首先声明了IPut的实例,该实例指向了类A的实例,此时通过IPut实例调用的PutName()方法,是类A的PutName()方法。再使IPut实例指向类B的实例,此时再通过IPut实例调用的PutName()方法,是类B的PutName()方法。从而实现了多态,即通过一个签名调用不同的实现。

原创粉丝点击