1 什么是接口
接口是指定一组函数成员而不实现它们的引用类型,所以只能类和结构来实现接口。
interfaceIInfo //声明接口 关键字+接口名称{ 方法 直接分号无方法体}
{
string GetName();
string GetAge();
}
classCA : IInfo //声明实现了接口的CA类
{
publicstring Name;
publicint Age;
publicstring GetName() //在CA类中实现两个接口方法
{
return Name;
}
publicstring GetAge()
{
return Age.ToString();
}
}
classCB : IInfo //必须在基类列表中列出接口名称
{
publicstring First;
publicstring Last;
publicdouble PersonAge;
publicstring GetName()
{
return First + "" + Last;
}
publicstring GetAge()
{
return PersonAge.ToString();
}
}
classProgram
{
staticvoid PrintInfo(IInfo item) //传入接口的引用
{
Console.WriteLine("Name:{0},Age{1}",item.GetName(),item.GetAge());
}
staticvoid Main()
{
CA a = newCA() { Name="John Doe",Age=35};
CB b = newCB { First = "Jone", Last = "Ane", PersonAge = 22 };
PrintInfo(a); //对象a的引用能自动转换为接口的引用 因为CA类是实现(继承)自接口
PrintInfo(b);
}
}
实现接口时,必须为接口的每一个成员提供实现。
2 接口声明
接口不能包含 数据成员 和 静态成员
接口只能包含 方法 属性 事件 索引器
接口声明,接口的前面可以有public等访问修饰符,而接口的成员是不允许有任何访问修饰符的,接口的成员都是隐式的public
3 接口实现
如果类从基类继承并实现了接口,基类列表中的基类名称必须放在所有接口之前,如下:
classDerived:MyBaseClass,IInfo,IEnumerable,IComparable
{
……
}
一个类可以实现多个接口,但是只能继承一个基类。
4 接口是引用类型
接口是一种引用类型
MyClass mc = new MyClass();
IIfc1 ifc=(IIfc1)mc;
ifc.PrintOut("hello");
这里MyClass类实现了接口IIfc1,可将类对象mc强制转换为接口类型的引用,然后调用引用方法
5 接口和as操作符
上面的强制转换如果类没有实现接口,则会抛出异常,所以使用as运算符。
ILiveBirth b= a as ILiveBirth;
当对象a的类没有实现ILiveBirth接口时,就给b赋值null。
6 实现多个接口
interfaceIDataRetrieve { int GetData();}
interfaceIDataStore { void SetData(int x);}
classMyData : IDataRetrieve, IDataStore
{
int Mem1;
publicint GetData() { return Mem1; }
publicvoid SetData(int x) { Mem1 = x; }
}
classProgram
{
staticvoid Main()
{
MyData data = newMyData();
data.SetData(5);
Console.WriteLine("Value={0}",data.GetData());
}
}
7 实现具有重复成员的接口
interfaceIIfc1 { void PrintOut(string s);} //两个接口有相同成员,方法签名和返回类型都一样
interfaceIIfc2 { void PrintOut(string t);}
classMyClass : IIfc1, IIfc2 //实现两个接口
{
publicvoid PrintOut(string s) //这里的实现是对两个接口的实现
{
Console.WriteLine("Calling through:{0}",s);
}
}
classProgram
{
staticvoid Main()
{
MyClass mc = newMyClass();
mc.PrintOut("Hello");
}
}
8 多个接口的引用
classProgram
{
staticvoid Main()
{
MyClass mc = newMyClass();
IIfc1 ifc1 = (IIfc1)mc;
IIfc2 ifc2 = (IIfc2)mc;
mc.PrintOut("Hello");//从类对象调用
ifc1.PrintOut("Interface 1");//从IIfc1调用
ifc2.PrintOut("Interface 2");//从IIfc2调用
}
}
9 派生成员作为实现
有一个派生类继承自基类,且实现了接口,如果在基类中有和接口成员匹配的成员,则派生类可以不再实现改成员。
interfaceIIfc1 { void PrintOut(string s);}
classMyBaseClass
{
publicvoid PrintOut(string s)
{
Console.WriteLine("Calling through:{0}", s);
}
}
classDerived : MyBaseClass, IIfc1
{ }
classProgram
{
staticvoid Main()
{
Derived d = newDerived();
d.PrintOut("HEllo");//通过派生类对象调用基类方法
}
}
10 显示接口成员实现
interfaceIIfc1 { void PrintOut(string s);}
interfaceIIfc2 { void PrintOut(string t);}
classMyClass : IIfc1, IIfc2
{
publicvoidIIfc1.PrintOut(string s)
{
Console.WriteLine("IIfc1:{0}", s);
}
publicvoidIIfc2.PrintOut(string s)//显示接口成员实现限定接口名
{
Console.WriteLine("IIfc2:{0}", s);
}
}
classProgram
{
staticvoid Main()
{
MyClass mc = newMyClass();
IIfc1 ifc1 = (IIfc1)mc;//获取IIfc1的引用
ifc1.PrintOut("interface 1");//调用显示实现
IIfc2 ifc2 = (IIfc2)mc;
ifc2.PrintOut("interface 2");
}
}
显示接口成员实现只可以通过指向接口的引用来访问,其他的类成员不能直接访问。
classMyClass : IIfc1
{
publicvoidIIfc1.PrintOut(string s)
{
Console.WriteLine("IIfc1:{0}", s);
}
publicvoid Method1()
{
PrintOut("hh");//编译错误
this.PrintOut("hh");//编译错误
((IIfc1)this).PrintOut("hh");//通过接口的引用类访问
}
}
其他类成员或者衍生类的成员都不能直接访问显示实现,只能通过接口的引用来访问。
11 接口可以继承接口
接口可以从一个或多个接口继承,子接口包含了自己所声明的成员和所有基接口的成员。
interfaceIDataRetrieve { int GetData();}
interfaceIDataStore { void SetData(int x);}
interfaceIDataTO : IDataRetrieve, IDataStore//IDataTO接口继承自前两个接口
{
}
classMyData :IDataTO
{
int Mem1;//类实现接口时,除了实现接口的成员还可以有其他自己的成员
publicint GetData() { return Mem1; }
publicvoid SetData(int x) { Mem1 = x; }
}
classProgram
{
staticvoid Main()
{
MyData data = newMyData();
data.SetData(5);
Console.WriteLine("Value={0}", data.GetData());
}
}
12 不同类实现一个接口的示例代码
interfaceILiveBirth
{
string BabyCalled();
}
classAnimal { }
classCat : Animal, ILiveBirth
{
stringILiveBirth.BabyCalled()
{ return"Kitten"; }
}
classDog : Animal, ILiveBirth
{
stringILiveBirth.BabyCalled()
{
return"puppy";
}
}
classBird : Animal
{ }
classProgram
{
staticvoid Main()
{
Animal[] animalArray = newAnimal[3];
animalArray[0] = newCat();
animalArray[1] = newDog();
animalArray[2] = newBird();
foreach (Animal a in animalArray)
{
ILiveBirth b = a asILiveBirth;
if (b != null)
Console.WriteLine("Baby is called:{0}",b.BabyCalled());
}
}
}
结果:
![]()