一、接口定义
接口是把公共实例(非静态)方法和属性组合起来,以封装特定功能的一个集合.一旦定义了接口,就可以在类中实现它.这样,类就可以支持接口所指定的所有属性和成员.
C#接口中包含方法、属性、索引器和事件的声明,但常用的接口中一般就是方法和属性。不能包含常量、字段、运算符、实例构造函数、析构函数等类型。 接口成员会自动成为公共成员,不能包含任何访问修饰符。 成员也不能是静态成员。
定义如下:
interface IEquatable
{
bool Equals(T obj); //默认自动为public
}
二、接口实现
接口不能单独存在,不能像实例化一个类那样实例化接口.另外,接口不能包含实现其成员的任何代码,而只能定义成员本身.实现过程必须在实现接口的类中完成,并且具有与接口成员相同的名称和签名。
下面的示例展示了 IEquatableCar
必须提供 Equals 方法的实现。
//默认隐式接口实现
public class Car : IEquatable
{
public string Make {get; set;}
public string Model { get; set; }
public string Year { get; set; }
// Implementation of IEquatable interface
public bool Equals(Car car)
{
if (this.Make == car.Make &&
this.Model == car.Model &&
this.Year == car.Year)
{
return true;
}
else
return false;
}
}
知识点:如果基类实现接口,则从基类派生的任何类都会继承该实现。
public class fish : Animal, ILiveInfo
{
void Eat()
{
//Eat func
}
}
public interface ILiveInfo
{
void Breath();
void Eat();
}
public class Animal()
{
void Breath()
{
//Breath func
}
}
由于fish继承接口ILiveInfo,那么它必须实现ILiveInfo中的所有接口函数,我们可以看到fish只实现了Eat()接口函数,并未实现Breath()接口函数。
注意:上述实现是OK的,因为fish继承自Animal,那么它通过继承父类也实现了Breath()方法。
三、接口调用
static void Main( string[ ] args )
{
Car c1 = new Car( );
c1.Make = "China";
c1.Model = "BYD";
c1.Year = "2001";
Car c2 = new Car( );
c2.Make = "Germany";
c2.Model = "BMW";
c2.Year = "1990";
//采用隐式接口实现时,类和接口都可以访问接口中的方法
/*利用类访问接口中的方法*/
if( true == c1.EqualsTo( c2 ) )
{
Console.WriteLine( "Equals true" );
}
else
{
Console.WriteLine( "Equals false" );
}
/*利用接口访问接口中的方法*/
IEquatable Ie = (IEquatable)c1;
if( true == Ie.EqualsTo( c2 ) )
{
Console.WriteLine( "Equals true" );
}
else
{
Console.WriteLine( "Equals false" );
}
}
定义:显示接口实现方式指的是在实现过程中,明确指出实现哪一个接口中的哪一个方法。
目的:当多个接口中包含相同方法名称、相同返回类型和相同参数时,如果一个类同时实现了这些接口,隐式的接口实现就会出现命名冲突问题。
//接口定义
interface IEquatable_A
{
bool EqualsTo( T obj ); //默认自动为public
}
interface IEquatable_B
{
bool EqualsTo( T obj ); //默认自动为public
}
//显示接口实现
public class Car_Double : IEquatable_A, IEquatable_B
{
public string Make{get;set;}
public string Model{get;set;}
public string Year{get;set;}
// Implementation of IEquatable interface
bool IEquatable_A.EqualsTo( Car_Double car )
{
Console.WriteLine( "Implementation of IEquatable_A" );
if( this.Make == car.Make &&
this.Model == car.Model &&
this.Year == car.Year )
{
return true;
}
else
return false;
}
bool IEquatable_B.EqualsTo( Car_Double car )
{
Console.WriteLine( "Implementation of IEquatable_B" );
if( this.Make == car.Make )
{
return true;
}
else
return false;
}
}
//接口调用
static void Main( string[ ] args )
{
//初始化类实例
Car_Double carD1 = new Car_Double( );
carD1.Make = "China";
carD1.Model = "BYD";
carD1.Year = "2001";
Car_Double carD2 = new Car_Double( );
carD2.Make = "Germany";
carD2.Model = "BMW";
carD2.Year = "1990";
IEquatable_A IeA = (IEquatable_A)carD1;
//采用显式接口实现时,只能通过接口来访问,不能通过carD1.EqualsTo(carD2)的方式
if( true == IeA.EqualsTo( carD2 ) )
{
Console.WriteLine( "Car_Double Equals true" );
}
else
{
Console.WriteLine( "Car_Double Equals false" );
}
Console.ReadKey( );
}
运行结果:
抽象类经常与接口一起使用,分析一下接口与抽象类的区别:
(1). 抽象类使用abstract关键字进行定义,而接口使用interface进行定义;它们都不能进行实例化。
(2). 抽象类中可以包含虚方法、非抽象方法和静态成员;但接口中不能包含需方法和任何静态成员,并且接口中只能定义方法,不能有具体实现,方法的具体实现由实现类完成。
(3). 抽象类不能实现多继承,接口则支持多继承。
四、面向对象编程的应用
假如我们定义如下Dog类继承自Animal类
public abstract class Animal
{
public void Eatfood( )
{
//eat some food
}
public void Walk( )
{
//walk
}
}
public class Dog : Animal
{
}
此时我们希望添加Show(),表演这个方法,由于并不是所有Dog都具有表演的属性,我们不应在Animal中实现Show方法,另外C#中又不支持多重继承,所以我们可以利用Interface来作为“替代版”的多重继承。
即:我们可以通过接口定义Show()方法,然后让具有表演才能的狗继承Dog类,并且实现具有表演才能Show方法的接口。
如下所示:
public interface IAnimalShow
{
void Show( );
}
public class SpecialDog : Dog, IAnimalShow
{
public void Show( )
{
}
}
参考文章:
https://blog.csdn.net/liuqinghui1990/article/details/77171051
http://wiki.jikexueyuan.com/project/csharp-confusing-concepts-summary/parse-interface.html