接口:interface
1.什么是接口
interface(接口)是一种引用类型,接口的内部规定了若干个未实现的函数成员。接口通常被当作“基类”一样使用,可以被其它类所继承。
【接口】用于反映一群【“大同小异”的类】所具有的共同特性;对于这些类而言,接口内部的函数成员,反映了这群相似的个体都能够执行的共同行为。
一旦一群不同的类继承了一个相同的接口,它们就必须实现接口中规定的所有共同行为;但是,每个类都能够以【个性化】的方式来执行这些行为。
上面的定义有点难懂,到底是什么意思呢?举个例子看一下。
狗、猫、猪都属于“动物”。
每种动物具有共同行为——它们都会发出叫声。但不同动物的叫声不同:狗的声音是Bark,猫的声音是Meow,猪的声音是Oink。
如果我们想让一只狗、一只猫、一头猪都发出叫声,传统的编程思想是这样的:
狗.叫( );
猫.叫( );
猪.叫( );
这真的太麻烦了!而且,这样的程序不具备可扩展性,如果新增一种动物 牛,那么程序还会变得更长、更复杂。
----------------
如何改进程序呢?我们希望能够对 (动物) 狗、猫、猪 下达统一的 鸣叫( ) 指令,这是一种优雅而便捷的程序实现方案。
在上面的想法中,"狗" "猫" "猪" 是三个不同的类,而“动物”则是这三个类都会继承的接口。
2.程序展示
using System;
namespace InterfaceShow
{
public interface IAnimal //接口:动物
{
void PlaySound();//所有继承本接口的类,都能够执行PlaySound()方法,来输出自己的叫声
}
public class Dog : IAnimal //定义了狗,狗属于动物,狗的叫声是Bark
{
public void PlaySound()
{
Console.WriteLine("Bark");
}
}
public class Cat : IAnimal //定义了猫,猫属于动物,猫的叫声是Meow
{
public void PlaySound()
{
Console.WriteLine("Meow");
}
}
public class Pig : IAnimal //定义了猪,猪属于动物,猪的叫声是Oink
{
public void PlaySound()
{
Console.WriteLine("Oink");
}
}
//到这里,狗、猫、猪三种不同的动物都拥有了自己专属的鸣叫指令,这些指令会根据自己类的不同来输出对应的叫声。
public class MainClass
{
//这里定义了“鸣叫”方法,此方法接收若干个属于【动物(IAnimal)】的类实例,并让它们发出鸣叫
//这些类实例的具体类型可能各不相同
//但是在IAnimal接口的统一归纳下
//只要它们都属于动物,就可以作为参数被传入这个方法,具体属于哪种动物不重要
public static void PlaySoundsOf(params IAnimal[] animals)
{
foreach(IAnimal a in animals)
{
a.PlaySound();
}
}
static void Main(string[] args)
{
Dog d = new Dog();//初始化一只狗
Cat c = new Cat();//初始化一只猫
Pig p = new Pig();//初始化一头猪
PlaySoundsOf(d, c, p);//现在,对狗、猫和猪下达统一的指令,令它们发出叫声
Console.ReadLine();
}
}
}
-----------------------------------
输出结果:
Bark
Meow
Oink
-----------------------------------
这样就大功告成啦。我们通过将Dog、Cat、Pig三个不同的类用一个统一接口IAnimal进行归纳,成功地改进了程序。
3.备注
Tips: 接口interface不能像一般的类一样被创建实例(即使是继承了接口的类实例,也不能作为接口的实例)
例如:
Ianimal[] animals = new Ianimal[10];//错误:接口不能作为实例出现
或者
Dog d = new Dog();
Ianimal animal = d;
//错误
//即使是继承了接口的类,也还是不能作为接口的实例出现
//注意与类继承的区分,因为子类确实是可以作为父类的实例出现的
以上两种内容都是错误的,编译不能通过;
但是接口可以作为形参的变量类型出现,例如
public static void DoWithAnimal(IAnimal animal){ }
这种表述是正确的,在使用这个方法时,传入任何一个继承了IAnimals接口的类实例即可。
类似这样:
public static void DoWithAnimal(IAnimal animal)
{
//实现方法......
}
static void Main(string[] args)
{
Dog D = new Dog();
DoWithAnimal(D);
}
此外,接口可以继承接口。如果接口B继承了接口A,那么所有基于接口B的类必须同时实现A和B的所有接口成员。
在下面的示例中,接口"鸟类"(IBird)继承自接口"动物"(IAnimal)。
类"老鹰"(Eagle)继承自接口IBird,
因此它既需要实现IAnimal的接口成员PlaySound,也需要实现IBird的接口成员Fly。
public interface IAnimal
{
void PlaySound();
}
public interface IBird : IAnimal
{
void Fly();
}
public class Eagle : IBird
{
public void Fly()
{
}
public void PlaySound()
{
}
}