接口
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()); } } } 结果: