什么是接口
接口,在表面上是由几个没有主体代码的方法、属性、索引器、事件,或者它们的组合的集合体,有唯一的名称,可以被类或结构或者其他接口所实现(或者也可以说继承)。它在形式上可能是如下的样子:
1 interface IBankAccount 2 { 3 //方法:存款 4 void PayIn(decimal amount); 5 //方法:取款 6 bool Withdraw(decimal amount); 7 //属性:账户余额 8 decimal Balance { get; } 9 }
接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。举个粗暴的例子,如果你是人,则必须能吃饭。那么吃饭就可以作为接口,但是接口并没有吃饭的具体代码,而人作为一个类,要实现吃饭这个技能,就要实现这个接口,实现接口时,把接口内声明的成员写上具体的代码,然后就可以用这个类的实例或者接口的实例去调用它。
但是问题又来了,人这个类完全可以直接将吃饭作为它的方法成员直接调用,又何必多此一举呢?使用接口也并没有多大的用处嘛,那我们为什么还要使用接口呢?不过你仔细想想,能吃饭的不仅仅有男人,有女人,还有各种生物,他们的吃饭行为是各不相同的啊。它们都是由类封装好了,吃饭也包括在里面,这时候如果你只研究吃饭,也不想管这个类还有什么功能和属性的时候,你会怎么办呢?
你可能会希望把吃饭这个行为从里面抽出来统一管理,并且希望这个行为还得具有一个标准,这样才方便嘛。可是编程的时候要怎么表示呢?我们可以将吃饭这个行为抽象出来,像个类一样,只要实现它,我们就可以知道他们是怎么吃饭了。而这个像类一样的东西就是接口。
知道了什么是接口,让我们看看怎么来使用接口。
怎么使用接口
1.定义接口。使用关键字interface来定义,接口名称一般以I开头。
注意:接口中只能包含方法、属性、索引器和事件的声明。不允许声明成员上的修饰符,即使是pubilc都不行,因为接口成员总是公有的,也不能声明为虚拟和静态的。如果需要修饰符,最好让实现类来声明。
可以在类外声明,也可以在类内声明。
比如我定义了一个demo接口
1 interface Idemo 2 { 3 void Test(); 4 string str { get; } 5 }
2.实现接口
实现接口有两种方式,有显式现和隐式实现。
2.1 隐式实现
类和接口都能调用到,我称之为隐式实现。
实现刚刚的接口。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace demo 8 { 9 interface Idemo //接口 10 { 11 void Test(); 12 string str { get; } 13 } 14 15 class Test1 : Idemo //实现接口的类,需要实现接口中的所有成员 16 { 17 string s = "hello"; 18 public void Test() //方法 19 { 20 Console.WriteLine("this is a demo."); 21 } 22 23 public string str //属性 24 { 25 get 26 { 27 return s; 28 } 29 } 30 31 static void Main(string[] args) 32 { 33 /*Test1 test1 = new Test1(); //类调用 34 test1.Test();*/ 35 Idemo demo = new Test1(); //接口调用 36 demo.Test(); 37 } 38 } 39 }
using System;
2.2 显式实现
只有接口才能实现。
继续刚刚的例子。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace demo 8 { 9 interface Idemo 10 { 11 void Test(); 12 string str { get; } 13 } 14 15 class Test1 : Idemo 16 { 17 string s = "hello"; 18 //public void Test() 19 void Idemo.Test() //不需要修饰符 //实现接口成员时指定接口 20 { 21 Console.WriteLine("this is a demo."); 22 } 23 24 //public string str 25 String Idemo.str //指定接口 26 { 27 get 28 { 29 return s; 30 } 31 } 32 33 static void Main(string[] args) 34 { 35 /*Test1 test1 = new Test1(); 36 test1.Test();*/ 37 Idemo demo = new Test1(); //接口调用 38 demo.Test(); 39 40 } 41 } 42 }
using System;
2.3 显示接口实现与隐式接口实现的适应场景
- 当类实现一个接口时,通常使用隐式接口实现,这样可以方便的访问接口方法和类自身具有的方法和属性。
- 当类实现多个接口时,并且接口中包含相同的方法签名,此时使用显式接口实现。即使没有相同的方法签名,仍推荐使用显式接口,因为可以标识出哪个方法属于哪个接口。
- 隐式接口实现,类和接口都可访问接口中方法。显式接口实现,只能通过接口访问。
2.4 接口的继承
接口也可以继承,继承方式与类相同。下面我们定义一个新接口 IDemo来继承Idemo。接着刚刚的例子。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace demo 8 { 9 interface Idemo 10 { 11 void Test(); 12 string str { get; } 13 } 14 15 interface IDemo : Idemo //继承Idemo所有的成员,新添加一个成员 16 { 17 void test(); 18 } 19 class Test1 : IDemo //实现所有成员 20 { 21 string s = "hello"; 22 public void Test() 23 //void Idemo.Test() //不需要修饰符 24 { 25 Console.WriteLine("this is a demo1."); 26 } 27 public string str 28 // String Idemo.str 29 { 30 get 31 { 32 return s; 33 } 34 } 35 public void test() 36 { 37 Console.WriteLine("this is a demo2 "); 38 } 39 40 static void Main(string[] args) 41 { 42 /*Test1 test1 = new Test1(); 43 test1.Test();*/ 44 //Idemo demo = new Test1(); 45 //demo.Test(); 46 IDemo demo = new Test1(); 47 demo.test(); 48 demo.Test(); 49 } 50 } 51 }
using System;
Ending。。。。。有不足之处多多指教。