先上代码:打印出什么?
package hack;
import click.CodeTalk;
public class TypeIt {
    private static class ClickIt extends CodeTalk {
        void printMessage() {
            System.out.println("Hack");
        }
    }    public static void main(String[ ] args) {
        ClickIt clickit = new ClickIt();
        clickit.doIt();
    }
}package click;
public class CodeTalk {
    public void doIt() {
        printMessage();
    }    void printMessage() {
        System.out.println("Click");
    }
}
    打印结果是:Click   很显然,对于private类型的方法,子类里面不能重写;但是这里是缺省的方法,子类里面也不能。
谁能解释下?

解决方案 »

  1.   

    java 中 四中访问权限 http://blog.csdn.net/fuuckwtu/article/details/6504161重写就意味着可以使用super();这个方法 也就意味着可以访问父类的方法 而子类的访问权限 只到达protected这一个层次因此只有protected以及权限大于他的public可以被继承
      

  2.   

    补充一点  子类和父类在同一个包下面 那么在子类里面也是可以重写缺省的方法的 如果不在一个包下面的话只能重写protected以及public了 
      

  3.   


    public class TypeIt {
    private static class ClickIt extends CodeTalk {
    void printMessage() {
    System.out.println("Hack");
    }
    } public static void main(String[] args) {
    ClickIt clickit = new ClickIt();
    clickit.doIt();
    }
    } class CodeTalk {
    public void doIt() {
    printMessage();
    } void printMessage() {
    System.out.println("Click");
    }
    }
    结果是:Hack  JDK1.5还好我想不通就运行看下结果。求解!!!!
      

  4.   

    我也来凑个热闹!
    --
    关于访问权限是:public > protected > 默认 > private 
    ·默认:就是什么都不写,它的真正名字是,“包访问权限”,即在同一个包内访问权限为public ,在包外就是private的了。
    ·protected:就是“继承访问权限”,它是要超越“包”的。包内,同上,public 。 “包”外分情况,如果有继承,也就相当于是 public 的。没有继承,就是 private的。
    ---
    你上面的例子是在两个包的文件,虽然有继承,还是不能重写那个 默认 权限的方法的。 
      

  5.   

    你说的不是Private,而是package,如果在一个包,应该可以。
      

  6.   

    在作为外包的类中,它含有的方法的访问权限必须是public或protected。
    你在ClickIt中定义的printMessage只属于这个类自己,而不是父类中的printMessage。
    ClickIt clickit = new ClickIt();
    clickit.doIt();
    这句是调用了父类中的doIt(),因为父类中的doIt()的访问权限是public,所以子类继承到了,doIt()方法找的是它本类中的printMessage(),所以输出的结果是Click.
      

  7.   

    不信你可以把父类中的printMessage()的访问权限设为public,结果就一定是Hack了。
      

  8.   

    这个问题,从JVM字节码来解答会一目了然。
    首先,先清楚一个概念,方法绑定:
    1. 静态绑定,就是在编译时就能确定给定的方法签名对应的方法体。在Java中,私有方法,构造器,父类的方法就是静态绑定,还包括那些编译时就可以确定方法体的方法。
    2. 动态绑定,就是在运行时才确定一个方法签名对应的方法体。用于实现多态,Java中大部分方法都是动态绑定的。在JVM上,静态绑定使用invokespecial指令,动态绑定使用invokvirtual。invokevirtual会根据方法签名从当前对象向他的父类进行搜索,直到找到一个方法为止。先看一下CodeTalk和TypeIt在不同包的情况,CodeTalk.class反编译后的结果:# 只截取了doIt方法
    public void doIt();
      Code:
       0:   aload_0
       1:   invokespecial   #2; //Method printMessage:()V
       4:   return  LineNumberTable:
       line 4: 0
       line 5: 4
    可以看到在doIt方法的字节码中,调用printMessage方法使用的指令是invokespecial:
    1:   invokespecial   #2; //Method printMessage:()V
    也就是说,doIt方法是静态绑定,并且绑定了CodeTalk.printMessage方法。所以这个方法会被调用,打印Click在看ColdTalk和TypeIt在同一包的情况,CodeTalk.class反编译后的结果:# 只截取了doIt方法
    public void doIt();
      Code:
       0:   aload_0
       1:   invokevirtual   #2; //Method printMessage:()V
       4:   return  LineNumberTable:
       line 16: 0
       line 17: 4可以看到printMessage方法调用使用的是invokevirtual,也就是方法是动态绑定的:
    1:   invokevirtual   #2; //Method printMessage:()V
    在调用clickIt.doIt()方法时,JVM会从ClickIt类开始向CodeTalk类搜索printMessage:()V这个方法,而ClickIt中定义了这个方法,所以直接返回。最后调用的是ClickIt.printMessage方法,打印Hack。之所以为什么CodeTalk和TypeIt两个类在不在相同包中,会导致printMessage方法调用指令不一样,这是由javac编译器保证的。
      

  9.   

    A package-private method cannot be directly overridden by a method in a different package.
    总结就是package-private方法不能直接被另外一个包中的方法覆盖
      

  10.   

    8.4.8.1 Overriding (by Instance Methods)
    An instance method m1 declared in a class C overrides another instance method, m2, declared in class A iff all of the following are true:    C is a subclass of A.    The signature of m1 is a subsignature (§8.4.2) of the signature of m2.    Either
            m2 is public, protected or declared with default access in the same package as C, or
            m1 overrides a method m3, m3 distinct from m1, m3 distinct from m2, such that m3 overrides m2. (间接覆盖)Moreover, if m1 is not abstract, then m1 is said to implement any and all declarations of abstract methods that it overrides.