c#接口容易被忽视的问题
今天在看“并发集合”的时候,接口IProducerConsumerCollection<T> 有一个方法是TryAdd(),表示“试图”去添加,然后ConcurrentQueue<T> 这个类继承了该接口,
根据我以前对接口的理解就是,ConcurrentQueue<T>这个类必须要实现TryAdd()方法才行。然后事实上,通过ConcurrentQueue<T>类的实力对象,根本点不出TryAdd方法
但是msdn上面对于ConcurrentQueue<T>类的说明,却明确说明了“显示实现”TryAdd接口方法。如果说实现了那为什么ConcurrentQueue<T>实例对象为什么点不出来TryAdd方法呢? 我搞不懂!后来问了一下人,他说“你去看看显示实现跟隐式实相关的资料”
诶,以前真没去关心,原来接口还分显示跟隐式。
一、接口的显示实现与隐式实现
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 显示接口隐式接口 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 myImplicitClass iClass = new myImplicitClass(); 14 iClass.myMethon(); 15 16 myExplicitClass eClass = new myExplicitClass(); 17 //类型转换成接口 18 (eClass as myInterface).myMethon(); 19 } 20 } 21 22 23 interface myInterface 24 { 25 void myMethon(); 26 } 27 28 public class myImplicitClass : myInterface 29 { 30 /// <summary> 31 /// 传统模式就是这种隐式模式来实现接口方法的 32 /// </summary> 33 public void myMethon() 34 { 35 Console.WriteLine("传统的隐式实现接口方法"); 36 } 37 } 38 39 public class myExplicitClass : myInterface 40 { 41 /// <summary> 42 /// 必须显示实现接口 接口名称.方法名 的方式来调用方法 43 /// </summary> 44 void myInterface.myMethon() 45 { 46 Console.WriteLine("显示实现接口方法"); 47 } 48 } 49 }
执行结果是:
那问题又来了,既然有隐式实现(默认实现方式)那还要显示干嘛?
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 class Program 10 { 11 static void Main(string[] args) 12 { 13 MyClass c = new MyClass(); 14 int i = c.Add(3); 15 Console.WriteLine(i); 16 } 17 } 18 19 interface addInterface 20 { 21 int Add(int i); 22 } 23 24 class BaseClass 25 { 26 public int Add(int i) 27 { 28 return i + 1; 29 } 30 } 31 32 33 class MyClass :BaseClass, addInterface 34 { 35 36 } 37 }
二、接口的显示实现的意义
像这样的一个程序接口addInterface1有一个Add方法,如果子类MyClass的没有去实现Add方法的话,其实也是可以正常运行的,因为基类实现了Add方法。
那如果说,现在子类也实现了Add方法的话会怎样?
添加了new 关键字就会覆盖基类的Add方法,那有没有一种方法既可以在子类中实现一个Add方法,又不会覆盖基类的Add方法呢?
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 class Program 10 { 11 static void Main(string[] args) 12 { 13 MyClass c = new MyClass(); 14 15 int i = c.Add(3); 16 Console.WriteLine("调用基类的Add方法结果是:"+i); 17 18 i = ((addInterface)c).Add(3); 19 Console.WriteLine("显示调用接口的Add方法结果是:" + i); 20 } 21 } 22 23 interface addInterface 24 { 25 int Add(int i); 26 } 27 28 class BaseClass 29 { 30 public int Add(int i) 31 { 32 return i + 1; 33 } 34 } 35 36 37 class MyClass :BaseClass, addInterface 38 { 39 int addInterface.Add(int i) 40 { 41 return i + i; 42 } 43 } 44 }
执行结果是: