﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-牛牛组合-文章分类-Java</title><link>http://www.blogjava.net/airong/category/40538.html</link><description>春风不相识，何事入罗帏？</description><language>zh-cn</language><lastBuildDate>Wed, 29 Jul 2009 12:06:57 GMT</lastBuildDate><pubDate>Wed, 29 Jul 2009 12:06:57 GMT</pubDate><ttl>60</ttl><item><title>Java需要引入闭包吗？</title><link>http://www.blogjava.net/airong/articles/288830.html</link><dc:creator>电子牛</dc:creator><author>电子牛</author><pubDate>Tue, 28 Jul 2009 18:33:00 GMT</pubDate><guid>http://www.blogjava.net/airong/articles/288830.html</guid><wfw:comment>http://www.blogjava.net/airong/comments/288830.html</wfw:comment><comments>http://www.blogjava.net/airong/articles/288830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/airong/comments/commentRss/288830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/airong/services/trackbacks/288830.html</trackback:ping><description><![CDATA[今天在javaeye论坛里看到的帖子，认真地从头看到尾，对闭包有了进一步的认识。感谢原帖楼主和所有回帖的朋友。<br />
<br />
原帖地址：<a target="_blank" href="http://www.javaeye.com/topic/412451">http://www.javaeye.com/topic/412451</a><br />
主题：再论闭包<br />
作者：步行者<br />
对闭包感兴趣的朋友可以移步去看看。<br />
<br />
首先，给出闭包的定义（定义说法比较多，本人偷懒，就直接从原帖里摘取了。）：<br />
<br />
<p style="margin: 0px; padding: 0px;"><strong style="font-weight: bold;"><span style="color: rgb(0, 0, 255);">闭包</span>&nbsp;<span style="color: rgb(255, 0, 0);">&nbsp;</span>&nbsp;</strong>是可以包含<span style="color: rgb(0, 0, 255);">自由（未绑定）变量</span>&nbsp;的代码块；这些变量不是在这个代码块或者任何全局上下文中定义的，而是在定义代码块的环境中定义。&#8220;闭包&#8221; 一词来源于以下两者的结合：要执行的代码块（由于自由变量的存在，相关变量引用没有释放）和为自由变量提供绑定的计算环境（作用域）。</p>
<p style="margin: 0px; padding: 0px;"><br />
</p>
<p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;可能上面的定义有点晦涩，下面看一下<span style="color: rgb(0, 0, 255);">《Python&nbsp;核心编程》</span>&nbsp;对&nbsp;<strong style="font-weight: bold;"><span style="color: rgb(0, 0, 255);">闭包&nbsp;<span style="font-weight: normal;"><span style="color: rgb(0, 0, 0);">的解释。</span></span></span></strong></p>
<p style="margin: 0px; padding: 0px;"><strong style="font-weight: bold;"><span style="color: rgb(0, 0, 255);"><span style="font-weight: normal;"><span style="color: rgb(0, 0, 0);"><br />
</span></span></span></strong></p>
<p style="margin: 0px; padding: 0px;"><strong style="font-weight: bold;"><span><span style="font-weight: normal;">&nbsp;&nbsp;&nbsp; 如果在一个内部函数里，对在外部作用域（但不是在全局作用域）的变量进行引用，那么内部函数就被定义为<strong style="font-weight: bold;"><span style="color: rgb(0, 0, 255);">闭包</span>&nbsp;</strong>。定义在外部函数内的但由内部函数引用或者使用的变量被称为<span style="color: rgb(0, 0, 255);">自由变量</span>&nbsp;。</span></span></strong></p>
<p style="margin: 0px; padding: 0px;"><strong style="font-weight: bold;"></strong></p>
<p style="margin: 0px; padding: 0px;"><strong style="font-weight: bold;"></strong></p>
<p style="margin: 0px; padding: 0px;"><strong style="font-weight: bold;"></strong></p>
<p style="margin: 0px; padding: 0px;">&nbsp;</p>
原帖中&#8220;liusong1111&#8221;回帖值得思考：<br />
<strong>[<em>closure作为一等公民，可以被一个普通的变量引用、传递。在ruby里意味着它是Proc的一个对象（实例），自然可以调用Proc的方法（比如
call）。以java的视角，类是用来组织数据的，不是描述行为。而对于ruby，行为也是数据，也可以用类描述，类也是对象，类的类还是对象，这才是
真正的Everything is
Object。楼主受java和java所谓的OO的影响太深，评判这些问题时，应该眼光往外多看看，避免思维定势。尤其应该深入学习一门带闭包的语言，
看看它到底是怎么用的。</em>]</strong><br />
<br />
首先，我同意可以用OO模拟闭包的观点，这已经由原帖作者&#8220;步行者&#8221;给出详细的例子了。但是这势必在一定程度上会增加代码的复杂度和臃肿度。我想，大部分时候大家更希望用更简洁的方法去完成同样的功能吧。<br />
<br />
另外，对于闭包会破坏OO的结构的争论，我更愿意从广义的角度来理解OO的定义。正如上面引用中所说，&#8220;<strong><em>以java的视角，类是用来组织数据的，不是描述行为。而对于ruby，行为也是数据，也可以用类描述，类也是对象，类的类还是对象</em></strong>&#8221;。如果采用闭包，那么这个内部函数中可以定义局部变量，同时它本身就是行为，此时具有属性和行为的闭包，何尝不可以看做是OO的呢？<br />
个人的观点是如果能达到以下两条，那么我支持Java中引入闭包：<br />
<br />
1）引入闭包能够在保证程序的可读性的基础上，简化程序编写的复杂度，降低代码的臃肿度。<br />
2）引入闭包至少能够保证在大部分情况下，程序的性能能够保持或者得到提升。（这里排出了极限情况）<br />
<br />
本人对闭包的了解还远远不够，计划有空闲的时候，认真地学习下闭包的知识和相关的应用。<br />
<br />
欢迎讨论。<br />
<br />
<img src ="http://www.blogjava.net/airong/aggbug/288830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/airong/" target="_blank">电子牛</a> 2009-07-29 02:33 <a href="http://www.blogjava.net/airong/articles/288830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]深入理解java多态性及个人的一点思考</title><link>http://www.blogjava.net/airong/articles/286340.html</link><dc:creator>电子牛</dc:creator><author>电子牛</author><pubDate>Fri, 10 Jul 2009 22:39:00 GMT</pubDate><guid>http://www.blogjava.net/airong/articles/286340.html</guid><wfw:comment>http://www.blogjava.net/airong/comments/286340.html</wfw:comment><comments>http://www.blogjava.net/airong/articles/286340.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/airong/comments/commentRss/286340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/airong/services/trackbacks/286340.html</trackback:ping><description><![CDATA[原作者thinkGhoster，链接<a href="http://blog.csdn.net/thinkGhoster/archive/2008/04/19/2307001.aspx">http://blog.csdn.net/thinkGhoster/archive/2008/04/19/2307001.aspx</a><br />对原文进行了适当的调整，更适合阅读。<br /><br /><b>注：</b>本人读后的一点思考在文章最后。<br /><p><strong><font style="background-color: rgb(255, 255, 255);" size="4" color="#339966">（一）相关类</font></strong></p><div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: rgb(230, 230, 230) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; width: 95%;"><div><img id="_8_178_Open_Image" onclick="this.style.display='none'; document.getElementById('_8_178_Open_Text').style.display='none'; document.getElementById('_8_178_Closed_Image').style.display='inline'; document.getElementById('_8_178_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="_8_178_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_8_178_Closed_Text').style.display='none'; document.getElementById('_8_178_Open_Image').style.display='inline'; document.getElementById('_8_178_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> A </span><span id="_8_178_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_8_178_Open_Text"><span style="color: rgb(0, 0, 0);">{<br /><img id="_44_91_Open_Image" onclick="this.style.display='none'; document.getElementById('_44_91_Open_Text').style.display='none'; document.getElementById('_44_91_Closed_Image').style.display='inline'; document.getElementById('_44_91_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="_44_91_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_44_91_Closed_Text').style.display='none'; document.getElementById('_44_91_Open_Image').style.display='inline'; document.getElementById('_44_91_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />         </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> String show(D obj)</span><span id="_44_91_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_44_91_Open_Text"><span style="color: rgb(0, 0, 0);">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />                </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">A and D</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />         }</span></span><span style="color: rgb(0, 0, 0);"> <br /><img id="_128_175_Open_Image" onclick="this.style.display='none'; document.getElementById('_128_175_Open_Text').style.display='none'; document.getElementById('_128_175_Closed_Image').style.display='inline'; document.getElementById('_128_175_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="_128_175_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_128_175_Closed_Text').style.display='none'; document.getElementById('_128_175_Open_Image').style.display='inline'; document.getElementById('_128_175_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />         </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> String show(A obj)</span><span id="_128_175_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_128_175_Open_Text"><span style="color: rgb(0, 0, 0);">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />                </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">A and A</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />         }</span></span><span style="color: rgb(0, 0, 0);"> <br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0, 0, 0);"> <br /><img id="_198_367_Open_Image" onclick="this.style.display='none'; document.getElementById('_198_367_Open_Text').style.display='none'; document.getElementById('_198_367_Closed_Image').style.display='inline'; document.getElementById('_198_367_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="_198_367_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_198_367_Closed_Text').style.display='none'; document.getElementById('_198_367_Open_Image').style.display='inline'; document.getElementById('_198_367_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> B </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> A</span><span id="_198_367_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_198_367_Open_Text"><span style="color: rgb(0, 0, 0);">{<br /><img id="_234_281_Open_Image" onclick="this.style.display='none'; document.getElementById('_234_281_Open_Text').style.display='none'; document.getElementById('_234_281_Closed_Image').style.display='inline'; document.getElementById('_234_281_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="_234_281_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_234_281_Closed_Text').style.display='none'; document.getElementById('_234_281_Open_Image').style.display='inline'; document.getElementById('_234_281_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />         </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> String show(B obj)</span><span id="_234_281_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_234_281_Open_Text"><span style="color: rgb(0, 0, 0);">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />                </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">B and B</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />         }</span></span><span style="color: rgb(0, 0, 0);"><br /><img id="_317_364_Open_Image" onclick="this.style.display='none'; document.getElementById('_317_364_Open_Text').style.display='none'; document.getElementById('_317_364_Closed_Image').style.display='inline'; document.getElementById('_317_364_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="_317_364_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_317_364_Closed_Text').style.display='none'; document.getElementById('_317_364_Open_Image').style.display='inline'; document.getElementById('_317_364_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />         </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> String show(A obj)</span><span id="_317_364_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_317_364_Open_Text"><span style="color: rgb(0, 0, 0);">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />                </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">B and A</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />         }</span></span><span style="color: rgb(0, 0, 0);"> <br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0, 0, 0);"><br /><img id="_386_387_Open_Image" onclick="this.style.display='none'; document.getElementById('_386_387_Open_Text').style.display='none'; document.getElementById('_386_387_Closed_Image').style.display='inline'; document.getElementById('_386_387_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="_386_387_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_386_387_Closed_Text').style.display='none'; document.getElementById('_386_387_Open_Image').style.display='inline'; document.getElementById('_386_387_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> C </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> B</span><span id="_386_387_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_386_387_Open_Text"><span style="color: rgb(0, 0, 0);">{}</span></span><span style="color: rgb(0, 0, 0);"> <br /><img id="_407_408_Open_Image" onclick="this.style.display='none'; document.getElementById('_407_408_Open_Text').style.display='none'; document.getElementById('_407_408_Closed_Image').style.display='inline'; document.getElementById('_407_408_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="_407_408_Closed_Image" style="display: none;" onclick="this.style.display='none'; document.getElementById('_407_408_Closed_Text').style.display='none'; document.getElementById('_407_408_Open_Image').style.display='inline'; document.getElementById('_407_408_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> D </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> B</span><span id="_407_408_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);">...</span><span id="_407_408_Open_Text"><span style="color: rgb(0, 0, 0);">{}</span></span><span style="color: rgb(0, 0, 0);"> </span></div></div><p><font size="4" color="#339966"><strong>（二）问题：以下输出结果是什么？</strong></font></p><div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: rgb(230, 230, 230) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; width: 95%;"><div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        <span style="color: rgb(0, 0, 0);">A a1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> A();<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        A a2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> B();<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        B b = </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> B();<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        C c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> C(); <br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        D d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> D(); <br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        </span><span style="color: rgb(0, 0, 0);">System.out.println(a1.show(b));   ①<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(a1.show(c));   ②<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(a1.show(d));   ③<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(a2.show(b));   ④<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(a2.show(c));   ⑤<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(a2.show(d));   ⑥<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(b.show(b));     ⑦<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(b.show(c));     ⑧<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />        System.out.println(b.show(d));     ⑨    </span></div></div><p><strong><font size="4" color="#339966">（三）答案</font></strong></p><p>              ①   A and A<br />              ②   A and A<br />              ③   A and D<br />              ④   B and A<br />              ⑤   B and A<br />              ⑥   A and D<br />              ⑦   B and B<br />              ⑧   B and B<br />              ⑨   A and D</p><p><font size="4" color="#339966"><strong>（四）分析</strong></font></p><p>        <font size="3">①②③比较好理解，一般不会出错。④⑤就有点糊涂了，为什么输出的不是"B and B”呢？！！先来回顾一下多态性。</font></p><p><font size="3">        运行时多态性是面向对象程序设计代码重用的一个最强大机制，动态性的概念也可以被说成“一个接口，多个方法”。Java实现运行时多态性的基础是动态方法调度，它是一种在运行时而不是在编译期调用重载方法的机制。</font></p><p><font size="3">       
方法的重写Overriding和重载Overloading是Java多态性的不同表现。</font></p><p><font size="3">       - <i><b>重写(Overriding)</b></i> 是父类与子类之间多态性的一种表现。</font><font size="3">如果在子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写
(Overriding)。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被“屏蔽”了。</font></p><p><font size="3">       - <i><b>重载(Overloading)</b></i> 是一个类中多态性的一种表现。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数类型，则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。</font></p><p><font size="3">        <font color="#0000ff"><strong><em>当超类对象引用变量引用子类对象时，被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法，但是这个被调用的方法必须是在超类中定义过的，也就是说被子类覆盖的方法。</em></strong></font> （但是如果强制把超类转换成子类的话，就可以调用子类中新添加而超类没有的方法了。）</font></p><p><font size="3">        好了，先温习到这里，言归正传！实际上这里涉及方法调用的优先问题
，优先级由高到低依次为：</font></p><p><font size="3">       this.show(O), <br /></font></p><p><font size="3">       super.show(O)，<br /></font></p><p><font size="3">       this.show((super)O),<br /></font></p><p><font size="3">       super.show((super)O)。让我们来看看它是怎么工作的。</font></p><p><font size="3">       
比如④，a2.show(b)，a2是一个引用变量，类型为A，则this为a2，b是B的一个实例，于是它到类A里面找show(B
obj)方法，没有找到，于是到A的super(超类)找，而A没有超类，因此转到第三优先级this.show((super)O)，this仍然是
a2，这里O为B，(super)O即(super)B即A，因此它到类A里面找show(A
obj)的方法，类A有这个方法，但是由于a2引用的是类B的一个对象，B覆盖了A的show(A obj)方法，因此最终锁定到类B的show(A
obj)，输出为"B and A”。</font></p><p><font size="3">       
再比如⑧，b.show(c)，b是一个引用变量，类型为B，则this为b，c是C的一个实例，于是它到类B找show(C
obj)方法，没有找到，转而到B的超类A里面找，A里面也没有，因此也转到第三优先级this.show((super)O)，this为b，O为C，
(super)O即(super)C即B，因此它到B里面找show(B
obj)方法，找到了，由于b引用的是类B的一个对象，因此直接锁定到类B的show(B obj)，输出为"B and B”。</font></p><p><font size="3">        按照上面的方法，可以正确得到其他的结果。</font></p><p><font size="3">       
问题还要继续，现在我们再来看上面的分析过程是怎么体现出蓝色字体那句话的内涵的。它说：当超类对象引用变量引用子类对象时，被引用对象的类型而不是引用
变量的类型决定了调用谁的成员方法，但是这个被调用的方法必须是在超类中定义过的，也就是说被子类覆盖的方法。还是拿a2.show(b)来说吧。</font></p><p><font size="3">       
a2是一个引用变量，类型为A，它引用的是B的一个对象，因此这句话的意思是由B来决定调用的是哪个方法。因此应该调用B的show(B
obj)从而输出"B and
B”才对。但是为什么跟前面的分析得到的结果不相符呢？问题在于我们不要忽略了蓝色字体的后半部分，那里特别指明：这个被调用的方法必须是在超类中定义过的，也就是被子类覆盖的方法。B里面的show(B
obj)在超类A中有定义吗？没有！那就更谈不上被覆盖了。实际上这句话隐藏了一条信息：它仍然是按照方法调用的优先级来确定的。它在类A中找到了
show(A obj)，如果子类B没有覆盖show(A obj)方法，那么它就调用A的show(A
obj)（由于B继承A，虽然没有覆盖这个方法，但从超类A那里继承了这个方法，从某种意义上说，还是由B确定调用的方法，只是方法是在A中实现而已）；
现在子类B覆盖了show(A obj)，因此它最终锁定到B的show(A obj)。这就是那句话的意义所在。</font></p><p><font size="3"><br /></font></p><p><font size="3" face="Arial"><u><b>个人读后的一点思考：</b></u></font></p><p><font size="3" face="Arial">第5个问题值得思考，输出 a2.show(c) ，答案是 B and A</font></p><p><font size="3" face="Arial"><b>分析：</b><br /></font></p><p><font size="3" face="Arial">a2是类A的引用变量，引用的是类B的一个实例对象。c是类C的一个实例。</font></p><p><font size="3" face="Arial">
1）this.show(c)，在A中找show(C obj)的方法，没有找到，进行第二步。 <br /></font></p><p><font size="3" face="Arial">2）super.show(c)，A没有超类，进行第三步。 <br /></font></p><p><font size="3" face="Arial">3）this.show(super(c)), super(c)是B，A中是没有show(B obj)方法的，但是这时候会继续往上找，找B的父类，super(B)是A，在A中找show(A obj), 找到了。 <br /></font></p><p><font size="3" face="Arial">4）a2引用的是类B的一个对象，由B来决定调用哪个方法，因为类B中覆盖了A的show(A obj)方法，因此最终用类B中的show(A obj)方法。 </font></p><p><font size="3" face="Arial">所以结论是这里super(O)是采用了</font><font size="3" color="#336600" face="Arial"><b>逐层往上寻找</b></font><font size="3" face="Arial">的方式，具体来说，父类找不到对应的show方法，就找父类的父类，如果还没有，继续往上找，直到找到根基类。</font></p><p><font size="3" face="Arial">为了验证作者原文中蓝色字体段文字的正确性，我测试了输出a1.show(c)，结果和预想的一样，是A and A. <br /></font></p><p><font size="3" face="Arial">这里，a1.show(c)和a2.show(c)的区别在于持有的引用对象的不同，a1是持有了A类的一个实例对象，而a2是持有了B类的一个实例对象，所以当都找到了A类中的<span id="_8_178_Open_Text"><span style="color: rgb(0, 0, 0);">show(A obj)时，引用的对象的类型决定了该调用哪个成员的方法，前提是这个被调用的方法必须被子类覆盖了。所以</span></span>a1.show(c)输出的是A and A，而 <span id="_8_178_Open_Text"><span style="color: rgb(0, 0, 0);"></span></span>a2.show(c)输出的是 B and A.</font><font size="3"><font color="#0000ff"><strong><em></em></strong></font></font></p><font size="4" color="#339966"><strong></strong></font><img src ="http://www.blogjava.net/airong/aggbug/286340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/airong/" target="_blank">电子牛</a> 2009-07-11 06:39 <a href="http://www.blogjava.net/airong/articles/286340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>