当前位置:编程学习 > JAVA >>

谜题70:(其实涉及到对于修饰符的一个理解)

先摘抄java解惑里面的一个谜题

1. 下面这个程序设计在不同的包中的两个类的交互,main方法位于hack.TypeIt中。那么,这个程序会打印什么呢?  
2. package hack; 
3. import click.CodeTalk; 
4. public class TypeIt { 
5.     private static class ClickIt extends CodeTalk { 
6.         void printMessage() { 
7.             System.out.println("Hack"); 
8.         } 
9.     } 
10.  
11.     public static void main(String[ ] args) { 
12.         ClickIt clickit = new ClickIt(); 
13.         clickit.doIt(); 
14.     } 
15. } 
16.  
17. package click; 
18. public class CodeTalk { 
19.     public void doIt() { 
20.         printMessage(); 
21.     } 
22.  
23.     void printMessage() { 
24.         System.out.println("Click"); 
25.     } 
26. } 
27.  
28. 本谜题看起来很直观。Hack.TypeIt的main方法对TypeIt.ClickIt类实例化,然后调用其doIt方法,该方法是从CodeTalk继承而来。接着,该方法调用printMessage方法,它在TypeIt.ClickIt中被声明为打印Hack。然而,如果你运行该程序,它打印的将是Click。怎么会这样呢? 
29.  
30. 上面的分析做出了一个不正确的假设,即Hack.TypeIt.ClickIt.printMessage方法覆写了click.CodeTalk.printMessage方法。一个包内私有的方法不能被位于另一个包中的某个方法直接覆写[JLS 8.4.8]。在程序中的这两个twoMessage方法是无关的,它们仅仅是具有相同的名字而已。当程序在hack包内调用printMessage方法时,运行的是hack.TypeIt.ClickIt.printMessage方法。这个方法将打印Click,这也就解释了我们所观察到的行为。 
31.  
32. 如果你想让hack.TypeIt.ClickIt中的printMessage方法覆写在Click.CodeTalk中的该方法,那么你必须在Click.CodeTalk中的该方法声明之前添加protected或public修饰符。要使该程序能够编译,你还必须在hack.TypeIt.ClickIt的覆写声明的前面添加一个修饰符,该修饰符与你在Click.CodeTalk的printMessage方法上放置的修饰符相比,所具备的限制性不能更多[JLS 8.4.8.3]。换句话说,两个printMessage方法可以都被声明为是public的,也可以都被声明为是protected的,或者,超类中的方法被声明为是protected,而子类中的方法被声明为是public的。无论你执行了上述三种修改中的任何一种,该程序都将打印Hack,从而表明确实发生了覆写。 
33.  
34. 总之,包内私有的方法不能直接被包外的方法声明所覆写。尽管包内私有的访问权限和覆写结合到一起会导致某种混乱,但是Java当前的行为是允许使用包的,以支持比单个的类更大的抽象封装。包内私有的方法是它们所属包的实现细节,在包外重用它们的名字是不会对包内产生任何影响的。 

1. </pre><pre name="code" class="java">然后,为么明明java语言规范里面说,private类型的方法才是不可重写的?这里默认类型的却不能重写了? 

1. </pre><pre name="code" class="java" style="text-align: left;"> 

1. <span style="font-family: simsun; font-size: 14px; line-height: 23px; "><span style="background-color: rgb(255, 255, 102); ">重写就意味着可以使用super();这个方法 也就意味着可以访问父类的方法 而子类的访问权限 只到达protected这一个层次因此只有protected以及权限大于他的public可以被继承。<span style="text-align: left; ">补充一点 子类和父类在同一个包下面 那么在子类里面也是可以重写缺省的方法的 如果不在一个包下面的话只能重写protected以及public了--------<a href="http://hi.csdn.net/zhoujiaolongde" target="_blank" style="color: rgb(51, 51, 51); text-decoration: none; font-weight: bold; background-color: rgb(246, 249, 254); ">zhoujiaolongde</a>的解释:链接查看:<a href="http://topic.csdn.net/u/20111214/14/acf69b6e-d7a4-4987-b481-b1c477154def.html">http://topic.csdn.net/u/20111214/14/acf69b6e-d7a4-4987-b481-b1c477154def.html</a></span></span></span> 

摘自 jiqikewang的专栏
 

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,