一个例子搞明白c#接口与封装变化的内涵
2013-06-23 12:04
453 查看
一个例子搞明白c#接口与封装变化的内涵
接口, 可理解是一个统一的方法供外界面调用。由于接口的多态,就可以实现封装变化的需要。
封装变化:把变化装在接口里面,不让外面知道。
看例子:
功能:把两个字符串用不同的符号连接起来,做为一个ID。
代码分析:
1、定义了一个接口MakeSvcId,接口有一个方法MakeID
2、两个类SlashId 和LineId继承了接口,实现MakeID的方法,SlashId 的MakeID方法通过斜线连接字符串,LineId的MakeID方法通过下滑线连接字符串。
3、最主要的一句话:
MakeSvcId MI= new SlashId();
声明一个接口类型的变量MI,但是将SlashId的实例附值给MI。然后MI.MakeID(a,b)产生输出字符串。
这里利用了接口的多态,执行哪个MakeID方法,取决与MI在运行时被附的值,而不是声明的类型。
这句把SlashId的实例的值附给MI,所以调用SlashId类内的MakeID方法。
你现在应该明白程序大体流程了吧?但是,也许你会产生一个疑问:这么麻烦有什么意思?我直接弄两个函数,写成这样:
这样的话,如果我想换另一种生成ID的方式,直接换另一个函数不就行了吗?
乍一看,确实是这么回事,但是当你的工程很庞大的时候,到处都在调用makeSlashID函数,忽然有一天,老板说这种ID不好用,换MakeLineID吧。怎么样?傻了吧。
用接口的方式就不会出现这种情况,因为函数调用的时候,类似这两句:
其它地方需要产生ID的时候,只需要MI.MakeID(a,b)就可以了。
如果老板说要换 LineID了。你只需要很悠闲的改成这样:
看到没,只改了一句话,所以调用MakeID的地方都不用变。
总体来看,接口就像各种管道的接口一样,你只需要接口怎么用,有什么功能,而不需要知道接口后面有什么。在这个例子里,我只调用接口的MakeID方法就行了。至于最终调用到了哪个实现类的方法,完全由运行时附的实例值决定。
没看明白,可以留言,文笔不好。
看明白了,不代表你就会了,闭上眼睛好好想想。
注:以上方法,只适合创建一个对象,调用不同方法的情况。如果工程中需要随时的创建和销毁对象,那么上面的模式就是失败的。因为代码会充满MakeSvcId MI= new LineId (),一旦要换成MakeSvcIdMI= new SlashId(),需要修改的地方仍然很多,增加了类间的耦合。且此时MakeSvcId MI=new SlashId()和SlashId MI= new SlashId()的差别并不大,而接口的抽象作用并没有体现出来。这时候,就要用到设计模式中的“工厂模式”了。
接口, 可理解是一个统一的方法供外界面调用。由于接口的多态,就可以实现封装变化的需要。
封装变化:把变化装在接口里面,不让外面知道。
看例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace EncapsulationTest { class Program { static void Main(string[] args) { string a = "a"; string b = "b"; MakeSvcId MI= new SlashId(); Console.WriteLine("产生的ID是:{0}",MI.MakeID(a,b)); //输出结果:a/b Console.ReadLine(); } } public interface MakeSvcId { string MakeID(string a, string b); } class SlashId :MakeSvcId { public string MakeID(string a,string b) { return a + "/" + b; } } class LineId : MakeSvcId { public string MakeID(string a,string b) { return a + "_" + b; } } }
功能:把两个字符串用不同的符号连接起来,做为一个ID。
代码分析:
1、定义了一个接口MakeSvcId,接口有一个方法MakeID
2、两个类SlashId 和LineId继承了接口,实现MakeID的方法,SlashId 的MakeID方法通过斜线连接字符串,LineId的MakeID方法通过下滑线连接字符串。
3、最主要的一句话:
MakeSvcId MI= new SlashId();
声明一个接口类型的变量MI,但是将SlashId的实例附值给MI。然后MI.MakeID(a,b)产生输出字符串。
这里利用了接口的多态,执行哪个MakeID方法,取决与MI在运行时被附的值,而不是声明的类型。
这句把SlashId的实例的值附给MI,所以调用SlashId类内的MakeID方法。
你现在应该明白程序大体流程了吧?但是,也许你会产生一个疑问:这么麻烦有什么意思?我直接弄两个函数,写成这样:
class prgram { private string MakeSlashID(string a,string b){}; private string MakeLineID(tring a,string b){}; static void Main(string[] args) { makeSlashID(a,b); } }
这样的话,如果我想换另一种生成ID的方式,直接换另一个函数不就行了吗?
乍一看,确实是这么回事,但是当你的工程很庞大的时候,到处都在调用makeSlashID函数,忽然有一天,老板说这种ID不好用,换MakeLineID吧。怎么样?傻了吧。
用接口的方式就不会出现这种情况,因为函数调用的时候,类似这两句:
MakeSvcId MI= new SlashId(); Console.WriteLine("产生的ID是:{0}",MI.MakeID(a,b));
其它地方需要产生ID的时候,只需要MI.MakeID(a,b)就可以了。
如果老板说要换 LineID了。你只需要很悠闲的改成这样:
MakeSvcId MI= new LineId (); //注意这句 Console.WriteLine("产生的ID是:{0}",MI.MakeID(a,b));//这句根本不用变
看到没,只改了一句话,所以调用MakeID的地方都不用变。
总体来看,接口就像各种管道的接口一样,你只需要接口怎么用,有什么功能,而不需要知道接口后面有什么。在这个例子里,我只调用接口的MakeID方法就行了。至于最终调用到了哪个实现类的方法,完全由运行时附的实例值决定。
没看明白,可以留言,文笔不好。
看明白了,不代表你就会了,闭上眼睛好好想想。
注:以上方法,只适合创建一个对象,调用不同方法的情况。如果工程中需要随时的创建和销毁对象,那么上面的模式就是失败的。因为代码会充满MakeSvcId MI= new LineId (),一旦要换成MakeSvcIdMI= new SlashId(),需要修改的地方仍然很多,增加了类间的耦合。且此时MakeSvcId MI=new SlashId()和SlashId MI= new SlashId()的差别并不大,而接口的抽象作用并没有体现出来。这时候,就要用到设计模式中的“工厂模式”了。
相关文章推荐
- CodeProject - 在C#使用SHGetFileInfo获取(管理)文件或者文件夹图标(C#封装Win32函数的一个例子)
- c#接口简单易懂的一个例子
- 一个简单的小例子让你明白c#中的委托
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- 收藏——在C#使用SHGetFileInfo获取(管理)文件或者文件夹图标(C#封装Win32函数的一个例子)
- 一个简单的小例子让你明白c#中的委托-终于懂了!
- 一个天气接口的封装及使用例子
- CodeProject - 在C#使用SHGetFileInfo获取(管理)文件或者文件夹图标(C#封装Win32函数的一个例子)
- Android设计模式之一个例子让你彻底明白工厂模式(Factory Pattern)
- C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子
- C# Remoting的一个简单例子
- C#封装、多态、抽象、接口、匿名方法等学习
- 一个极其简单的在线C#IDE例子(zz)
- 第二个例子展示了如何使用一个提供单接口的COM对象QueryInterface()函数
- C#的一个客户端和服务器端例子
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- 一个例子让你明白原型对象和原型链
- 一个简单的C#多线程间同步的例子
- 一个验证码的例子(asp.net c#)
- 一个体现Java接口及工厂模式优点的例子