12.2 声明和实现接口

先来定义两个接口,每个都仅定义了一个方法成员,如代码清单12-2所示。

代码清单12-2 接口的定义


interface ISample

{

void Method1();

}

interface ISample2

{

void Method2();

}


我们在上述代码中定义了两个接口:ISample和ISample2。在接口的定义中省略了访问修饰符,那么意味着它们当前的访问级别是internal,即只能被同程序集的类“看到”并实现,而在程序集外根本无法“看到”。大家注意到了,这两个接口名称分别为ISample和ISample2。说到这里,顺便介绍一下接口的命名规则。接口的命名一般使用名词或名词短语,或者描述行为的形容词,尽可能少用缩写,不要使用下划线字符,大小写采用Pascal风格,即首字母和后面的每个单词的首字母都大写,其他字母小写。大家可能注意到了接口名字前的前缀I,它表示这个类型是一个接口。下面是几个合乎规范的例子:

❑IComponent(描述性名词)

❑IUserService(名词短语)

❑IDisposable(形容词)

请注意,上述接口命名的规则只是一个推荐规则,并非标准,具体规则应以您所在单位或者组织的规定为准。

截至目前,我们已经定义了两个接口,下一步要学习如何实现一个接口。从一定意义上说,接口只是表示其所定义成员的一种存在性,它是一个契约。

实现一个接口的语法如图12-4所示。

12.2 声明和实现接口 - 图1

图 12-4 类实现接口

接下来,我们对定义接口的几个关键部分进行说明,如表12-2所示。

12.2 声明和实现接口 - 图2

我们继续举例说明,先定义两个类,分别实现接口ISample和ISample2,如代码清单12-3所示。

代码清单12-3 实现接口


1 class ClassOne:ISample

2{

3 public void Method1()

4{

5 System.Console.WriteLine("from ClassOne.Method1()");

6}

7

8 public void Method2()

9{

10 System.Console.WriteLine("from ClassOne.Method2()");

11}

12}

13

14 class ClassTwo:ISample

15{

16 public void Method1()

17{

18 System.Console.WriteLine("from ClassTwo.Method1()");

19}

20}


上述代码的实现接口如图12-5所示。

12.2 声明和实现接口 - 图3

图 12-5 实现接口

关于代码清单12-3的说明如表12-3所示。

12.2 声明和实现接口 - 图4

接下来,我们来看看如何调用这两个实现类,如代码清单12-4所示。

代码清单12-4 实例化接口的实现类


class ClassExample

{

public static void Main()

{

ISample sample1=new ClassOne();

ISample sample2=new ClassTwo();

sample1.Method1();

sample2.Method1();

}

}


这段代码的执行结果如下:


from ClassOne.Method1()

from ClassTwo.Method1()


在上述代码中,要特别关注的是声明了两个类型为ISample的变量sample1和sample2,它们分别使用ClassOne和ClassTwo类进行了初始化。这说明接口类型的变量可以指向任何实现了这个接口的类的实例,这样固然很好,可以灵活地指定某个实现类,而不需要改变依赖这个接口的代码。但这样一来就只能通过这些接口类型的引用调用接口的方法,如果想要调用某个实现类中的自定义的、不在接口中的方法,就需要把引用强制类型为合适的类型。下面通过一个例子进行说明。

在ClassOne类中添加一个Method2方法,该方法的定义并未出现在接口ISample中,因此它属于ClassOne类,通过ISample接口的引用将无法看到访问到它,必须将ISample接口的引用向下转型到ClassOne类型才能进行访问,如代码清单12-5所示。

代码清单12-5 通过向下转型调用接口实现类的专属方法示例


1 class ClassOne:ISample

2{

3 public void Method1()//定义于ISample接口中的方法

4{

5 System.Console.WriteLine("from ClassOne.Method1()");

6}

7

8 public void Method2()//专属于ClassOne类的方法

9{

10 System.Console.WriteLine("from ClassOne.Method2()");

11}

12}

13

14 class ClassTwo:ISample

15{

16 public void Method1()//定义于ISample接口中的方法

17{

18 System.Console.WriteLine("from ClassTwo.Method1()");

19}

20}

21

22 class ClassExample

23{

24 public static void Main()

25{

26 ISample sample1=new ClassOne();

27 ISample sample2=new ClassTwo();

28 sample1.Method1();

29 sample2.Method1();

30//将ISample类型的引用向下转型到ClassOne类型的引用

31 ClassOne clsOne=(ClassOne)sample1;

32 clsOne.Method2();

33}

34}