2013-03-24 87 views
3

我正在阅读“Thinking in Java”并且有疑问。在“重用类”一章中,“最终和私有”一节中,它指出私有方法不能被覆盖。不过,我在机器上试了一下。它实际上可以被覆盖。覆盖私有方法

下面是代码

class Amphibian { 
    private void print() { System.out.println("in Amphibian"); } 
} 

public class Frog extends Amphibian { 
    public void print(System.out.println("in Frog"); } 

    public static void main(String[] args) { 
      Frog f = new Frog(); 
      f.print(); 
    } 
} 
+1

你的代码实际上并没有编译。 – millimoose 2013-03-24 18:55:42

+0

它编译在我的机器上。 – NoviceCai 2013-03-24 19:12:29

+0

然后代码“在您的机器上”与您的问题中的代码不相同,因为该代码明显被破坏。 – millimoose 2013-03-24 19:17:54

回答

12

你没有覆盖它,你只是躲在与具有相同名称的新方法。

如果您没有创建新的print()方法,那么您的Frog类将不会有一个。

+2

确切地说,使用'@ Override'注释,你会得到一个错误:) – 2013-03-24 18:53:37

+1

好的。谢谢。所以没有@override,它只是隐藏定义而不是覆盖它。 – NoviceCai 2013-03-24 18:54:51

+0

是的,确切地说。 '@ Override'将检查你是否实际覆盖了一个继承的方法。如果你输错了,或者如果没有任何方法,你会覆盖,它会标记为错误 – 2013-03-24 18:56:50

4

为了说明重写和隐藏之间的差异,可以这样考虑:

class Amphibian { 
    private void print() { System.out.println("in Amphibian"); } 
    public void callPrint() { 
     /* 
     * This will DIRECTLY call Amphibian.print(), regardless of whether the 
     * current object is an instance of Amphibian or Frog, and whether the 
     * latter hides the method or not. 
     */ 
     print(); // this call is bound early 
    } 
} 

class Frog extends Amphibian { 
    public void print() { System.out.println("in Frog"); } 
    public static void main(String[] args) { 
     Frog f = new Frog(); 
     f.callPrint(); // => in Amphibian 

     // this call is bound late 
     f.print(); // => in Frog 
    } 
} 

的“首要”(即隐藏)方法不会被调用,所述一个在父类中一样。这意味着它不是真正的覆盖。

+0

这是一个小技巧。如果您使用两栖动物私密打印,则无法覆盖它。但是,如果你公开,不管你是否使用@Override,它总是会在Frog中被覆盖。 – NoviceCai 2013-03-24 19:05:36

+0

我试着让你的代码公开,并且把@Override放在Frog的print前面。我得到了同样的结果。 – NoviceCai 2013-03-24 19:06:22

+1

@NoviceCai没有涉及的技巧,这就是Java的工作方式。 '@ Override'不会改变代码的语义,如果注释的方法没有覆盖任何东西,它只会让Java编译器给你一个错误。注释的目的是捕捉错误,而不是在基类中重写一个方法。任何*虚拟*方法都可以并且将被另一种在子类中具有兼容签名的方法覆盖。 IIRC,在Java中,每个非'private'方法都是虚拟的,不管其他方法如何注解。 – millimoose 2013-03-24 19:21:11

0

您可以简单地在subclass中编写private方法,但不会被覆盖。但它仍然遵循其在覆盖

使用如果您在superclass方法更广泛地access modifier(默认情况下,保护公众)当subclass's方法是私有的,然后编译器显示错误的访问修饰符规则。它遵循覆盖规则,但不会实际覆盖。