接口与抽象类

其实没有那么高深,几句话就能说清楚。

问lz几个问题
(1)如果我写一个代码交给lz维护,你是愿意在我的代码中改来改去呢,还是直接再按照一定规则编写一段代码来扩展呢?
(2)如果lz是一个框架库的编写者(这听上去有点高级),你的用户不再是最终用户,而是一些初级程序员,你如何让他们觉得你的框架库好用。比如你的框架库应该适应尽可能多的情况(这些情况你不能一一预料到并且写在代码中),同时还要避免他们修改你的代码(你的代码已经编译成dll了)。

也许具体怎么做你不知道,但是看了我的两点,原则你已经知道了,那就是你编写的代码必须 对功能的扩展开放 (允许他们扩展功能),同时 对修改关闭 (程序本身不应该被修改,就像你不会随便修改System.Data,System.Web中的代码,实际上也没有代码给你修改)。

这个原则很多程序员已经意识到了,于是简称为OCP(开放关闭原则)。

那么接口、抽象类的作用是什么呢?它就是使得你的代码符合这个原则:

我们看这么一个场景,我们编写的程序提供了日志输出的功能:

C# code
   
   
foo() { ... try { ... } catch (Exception ex) { Console.WriteLine(ex.Message); } ... }


这个程序作为直接给最终用户编码的程序,显然没有什么问题。

但是你可能意识到了,这个程序只能在控制台上才能显示错误,如果是在ASP.NET中,我们需要把输出的方式修改下才行。那么WinForms呢?我们还得修改。这对于一个通用的函数库来说,显得不可以接受。
当然你可以做一个判断,并且把这三种形式都包括在内。可是真的只有三种么?

如果调用你的程序员说,我想把错误输出到日志文件中,你不得不再增加第四种输出方式。

如果用接口,就没有问题了。

我们定义一个接口:
C# code
   
   
ILogger { void WriteLine( string content); }


这个接口表示,我们允许用户传递一个可以包含WriteLine方法的类,具体什么类不重要,只要它能有这个方法就可以了。

我们的代码修改如下:
C# code
   
   
foo(ILogger log) { ... try { ... } catch (Exception ex) { log.WriteLine(ex.Message); } ... }


这样,我们的程序就把输出到哪里从程序中提取出来了,让调用者决定。

如果调用者在编写一个控制台程序,他可以这么用:
C# code
   
   
class ConsoleLog : ILogger { public void WriteLine( string content) { Console.WriteLine(content); } } ... foo( new ConsoleLog());


如果调用者在写asp.net程序,它只需要定义另一个类就可以了
C# code
   
   
class ResponseLog : ILogger { public void WriteLine( string content) { Response.WriteLine(content); } } ... foo( new ResponseLog());


很明显没,如果他想输出到文件,或者显示在别的地方,都只需要自己定义一个类,实现这个接口,再传进去就能办到了。也就是不修改你的代码,在你的代码上扩充,实现无限的扩展。

这就很好回答了最初的两个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值