.Net平台中虚方法的好处之个人见解
2012-02-07 19:39
211 查看
虽然机房收费系统的代码已经写完了,但是对于.net平台的一些机制的认识还是模模糊糊,记得在学习设计模式的时候就遇到了“虚方法”这个概念,但是对于“虚方法”的认识却好似一团迷雾,今天下午花了一个多小时的时间来研究这个小东东,现在总结一下对“虚方法”的认识,如有不合理之处,望各位大牛们多多斧正。
对于虚方法的官方解释比较复杂,这里就用我的理解来个通俗的解释。虚方法是相对于非虚的方法而言的,两者的区别体现在基类和派生类中的运用上。下面通过网上粘来的一个小例子来说明问题。
运行结果是:A.F B.F B.G B.G
先分析一下这个小例子:
在这个例子中,派生类B继承了基类A;在基类A中,包含了一个非虚的方法 F 和一个虚方法 G ;在派生类 B中,引入了一个新的非虚方法 F(重写了父类的实体方法),因为这个方法与基类的非虚方法同名,因此就覆盖了从基类中继承来的方法F,另外在派生类B中还重写了继承来的虚方法 G。(这里网上多数都是说重载,但我觉得应该是重写,因为重载是发生在同一个类中,而重写才是子类与父类间的继承关系,或许重载可泛指重载和重写)
下面是我对运行结果的理解:
首先明白类的继承的一点知识:继承关系中子类可以重写父类里的所有方法,不管父类是不是抽象类,也不管父类中的方法是不是抽象方法。
结合现实生活,分析一下实体方法和虚方法的机制区别:
实体方法(非虚的方法)相当于现实生活中的实体物;虚方法仅相当于一个物体的名字,不具有真实的物质实体。派生类B继承基类A,重写了父类的实体方法和虚方法,但是这两种方法的运行机制是不同的:
虚方法:
相当于现实生活的一个箱子,不管原来这个箱子内部是不是存放着物体(不管基类中的虚方法有没有 默认函数),如果我要往里面重新放了东西的话,这个箱子里装的东西是我最终放进去的物体,这样我在运用箱子这个封装着物体的类(对象)的时候,实际上得到的是里面的物体,而我在需要的时候只需要指定我要用几号箱子即可,这就是.net平台中虚方法的好处,至于好处在程序中的具体运用稍后再谈,这里继续对比实体方法的运行机制。
实体方法:
实体方法好比一个真实的物体的存在,比如说家里有一块铁,父亲(Father)把它炼成了铁锤,而我(Son)却又把这块铁炼成了剑。这里炼铁的方法可用Shape(byval iron as 铁块) as Tool 。当你在实例化的时候,如果指明生成的是父亲类,那么Shape方法得到的就是铁锤,如果实例化的是Son类,那么调用Shape方法则得到一把剑。
对比以上理解,我们不难明白为什么最初的小例子中的运行结果是:A.F(基类实体方法,父亲用铁块炼出了铁锤) B.F (儿子用铁块炼成了) B.G (将A号箱子里放的东西换成B号箱子里的物体,但是标签(箱子号)依然是A,得到的物体是B箱子里的了) B.G (直接就是B号箱子里的物体)
以上用了不少篇幅在分析.net平台的虚方法和实体方法的区别机制,但是.net平台(面向对象编程思想)引入了继承机制,虚、实方法有什么好处?
实体方法很常见,我就不多说了,这里着重结合机房收费系统总结一下虚方法的应用。
我们都知道在D层基本上都是一些增、删、改、查的方法,根据这些共同的地方,我们可以在D层抽象出一个基类(DataBase),专门封装这些公共的方法,然后让具体的D层类来继承这个基类,也就是说在D层的派生类中重写基类的增、删、改、查方法。然后在B层调用的时候只需要实例化D层这个基类,然后再将具体的D层的某个对应实体类的类传给这个基类即可,也就是上面那个例子的B b = new B(); A a =
b; 这样程序在维护的时候就比较容易。
在这里我们肯定会想到D层的辅助类SqlHelp这个类,SqlHelp只是对D层的一些重复的方法,或者代码个隔离,是一些公共的执行动作的封装,与这里的DataBase并不冲突,一个是单纯代码层次的优化,另一个是.net平台机制的合理运用(或是面向对象思想的优点?),两者完全可以结合使用。
另一个问题就是这样一个封装虚方法的DataBase基类和大多数同学运用的D层的接口的设计模式有什么关系?
我认为,这里谈到的是两个不同层次的问题,抽象工厂+配置文件+反射+接口这些组合是利用分层的设计模式将D层和B层解耦,而这里谈到的虚方法可以侧重看成是.net机制的一种技术,好比泛化技术(对接口、类的进一步抽象,也是多态机制的基础)一样,便于代码的优化和程序的维护。
对于虚方法的理解就总结到此,这里只是个人的一些想法,还没有代码实现,上文中如有失当或者错误的地方望多多指导!
对于虚方法的官方解释比较复杂,这里就用我的理解来个通俗的解释。虚方法是相对于非虚的方法而言的,两者的区别体现在基类和派生类中的运用上。下面通过网上粘来的一个小例子来说明问题。
class A { public void F() { Console.WriteLine( "A.F "); } public virtual void G() { Console.WriteLine( "A.G "); } } class B: A { new public void F() { Console.WriteLine( "B.F "); } public override void G() { Console.WriteLine( "B.G "); } } class Test { static void Main() { B b = new B(); A a = b; a.F(); b.F(); a.G(); b.G(); } }
运行结果是:A.F B.F B.G B.G
先分析一下这个小例子:
在这个例子中,派生类B继承了基类A;在基类A中,包含了一个非虚的方法 F 和一个虚方法 G ;在派生类 B中,引入了一个新的非虚方法 F(重写了父类的实体方法),因为这个方法与基类的非虚方法同名,因此就覆盖了从基类中继承来的方法F,另外在派生类B中还重写了继承来的虚方法 G。(这里网上多数都是说重载,但我觉得应该是重写,因为重载是发生在同一个类中,而重写才是子类与父类间的继承关系,或许重载可泛指重载和重写)
下面是我对运行结果的理解:
首先明白类的继承的一点知识:继承关系中子类可以重写父类里的所有方法,不管父类是不是抽象类,也不管父类中的方法是不是抽象方法。
结合现实生活,分析一下实体方法和虚方法的机制区别:
实体方法(非虚的方法)相当于现实生活中的实体物;虚方法仅相当于一个物体的名字,不具有真实的物质实体。派生类B继承基类A,重写了父类的实体方法和虚方法,但是这两种方法的运行机制是不同的:
虚方法:
相当于现实生活的一个箱子,不管原来这个箱子内部是不是存放着物体(不管基类中的虚方法有没有 默认函数),如果我要往里面重新放了东西的话,这个箱子里装的东西是我最终放进去的物体,这样我在运用箱子这个封装着物体的类(对象)的时候,实际上得到的是里面的物体,而我在需要的时候只需要指定我要用几号箱子即可,这就是.net平台中虚方法的好处,至于好处在程序中的具体运用稍后再谈,这里继续对比实体方法的运行机制。
实体方法:
实体方法好比一个真实的物体的存在,比如说家里有一块铁,父亲(Father)把它炼成了铁锤,而我(Son)却又把这块铁炼成了剑。这里炼铁的方法可用Shape(byval iron as 铁块) as Tool 。当你在实例化的时候,如果指明生成的是父亲类,那么Shape方法得到的就是铁锤,如果实例化的是Son类,那么调用Shape方法则得到一把剑。
对比以上理解,我们不难明白为什么最初的小例子中的运行结果是:A.F(基类实体方法,父亲用铁块炼出了铁锤) B.F (儿子用铁块炼成了) B.G (将A号箱子里放的东西换成B号箱子里的物体,但是标签(箱子号)依然是A,得到的物体是B箱子里的了) B.G (直接就是B号箱子里的物体)
以上用了不少篇幅在分析.net平台的虚方法和实体方法的区别机制,但是.net平台(面向对象编程思想)引入了继承机制,虚、实方法有什么好处?
实体方法很常见,我就不多说了,这里着重结合机房收费系统总结一下虚方法的应用。
我们都知道在D层基本上都是一些增、删、改、查的方法,根据这些共同的地方,我们可以在D层抽象出一个基类(DataBase),专门封装这些公共的方法,然后让具体的D层类来继承这个基类,也就是说在D层的派生类中重写基类的增、删、改、查方法。然后在B层调用的时候只需要实例化D层这个基类,然后再将具体的D层的某个对应实体类的类传给这个基类即可,也就是上面那个例子的B b = new B(); A a =
b; 这样程序在维护的时候就比较容易。
在这里我们肯定会想到D层的辅助类SqlHelp这个类,SqlHelp只是对D层的一些重复的方法,或者代码个隔离,是一些公共的执行动作的封装,与这里的DataBase并不冲突,一个是单纯代码层次的优化,另一个是.net平台机制的合理运用(或是面向对象思想的优点?),两者完全可以结合使用。
另一个问题就是这样一个封装虚方法的DataBase基类和大多数同学运用的D层的接口的设计模式有什么关系?
我认为,这里谈到的是两个不同层次的问题,抽象工厂+配置文件+反射+接口这些组合是利用分层的设计模式将D层和B层解耦,而这里谈到的虚方法可以侧重看成是.net机制的一种技术,好比泛化技术(对接口、类的进一步抽象,也是多态机制的基础)一样,便于代码的优化和程序的维护。
对于虚方法的理解就总结到此,这里只是个人的一些想法,还没有代码实现,上文中如有失当或者错误的地方望多多指导!
相关文章推荐
- Android对ViewGroup中OnMeasure方法的一些个人见解
- .NET平台下基于webservice,通过获取硬件cpu序列号和随机字符串序列号实现软件加密的一种方法。
- 【转】dodo:人脸识别方法个人见解(一)
- jenkins部署.net平台自动化构建的方法步骤
- [C#技术] .NET平台开源JSON库LitJSON的使用方法
- javascript获取querystring值【个人觉得这种方法最好最棒最像.NET】
- 人脸识别方法个人见解
- .net 委托的使用方法以及使用委托的好处
- [C#技术] .NET平台开源JSON库LitJSON的使用方法
- .net平台是什么?.net平台的组成,.net平台的好处
- 人脸识别方法个人见解
- 手写DIV+CSS代码的好处我的个人见解
- 基于.Net平台应用系统设计方法
- .NET编译项目时出现《此实现不是 Windows 平台 FIPS 验证的加密算法的一部分》处理方法
- dodo:人脸识别方法个人见解
- uCOs 查找最高优先级任务的方法和我个人的见解
- .Net平台下的扩展方法
- Collection接口方法与使用(重写老师的课堂代码+个人见解)
- .Net业务平台的数值精度陷阱与解决方法
- 人脸识别方法个人见解