2012-01-27 46 views
6

方法繼承方法的知名度,我得到這個編譯器錯誤:不能減少從父

You cannot reduce the visibility of a inherited method.

我有以下代碼

class Parent {  
    public void func() { 
     System.out.println("in Parent"); 
    } 
} 

public class TestClass extends Parent {  
    public static void main(String args[]) { 
     parent obj=new TestClass(); 
     obj.addTest(); 
    } 

    private void func() { 
     System.out.println("in child");   
    } 
} 

這裏父類有func()方法,它是公開的,由覆蓋子類TestClass這是私人的。現在編譯器會拋出錯誤,我不能降低可見性。從技術上講,每當我創建TestClass指定給父類型對象的對象時,由於func()方法被覆蓋,所以TestClass的func()將始終被調用,那麼爲什麼我們應該關注可見性?這個錯誤背後的原因是什麼?有人能解釋清楚嗎?

回答

20

這是因爲子類具有的void func()方法private知名度,但超有知名度public

如果你的代碼被允許編譯,它會在運行時發生爆炸,如果你這樣做:

parent p = new TestClass(); 
p.func(); // boom - func is public in parent, but TestClass's impl is private, so no access would be allowed 

「修理」 這一點,讓子類的func方法public

public class TestClass extends parent { 
    ... 
    public void func() { // give it public visibility 
     System.out.println("in child");   
    } 
} 


請使用標準的命名約定;在這種情況下「類應該開始一個大寫字母」 - 即Parentparent

+0

謝謝Bohemain。我明白了理由。感謝您指出命名標準。 – Mojoy 2012-01-27 19:16:43

+0

嗨..這讓我想到爲什麼我不能在超類中公開的方法在子類中保護修飾符?由於受保護的修飾符可以在任何包的包和子類中訪問! – Mojoy 2012-01-28 13:40:47

+0

受保護的方法對其他任意類都不可見,但super的'public'方法是,所以同樣的推理適用。 *任何*可見度降低都是錯誤的。 – Bohemian 2012-01-28 19:21:14

11

section 8.4.8.3 of the Java Language specification

The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, or a compile-time error occurs. In more detail:

  • If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
  • If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise, a compile-time error occurs.
  • If the overridden or hidden method has default (package) access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs.

Note that a private method cannot be hidden or overridden in the technical sense of those terms. This means that a subclass can declare a method with the same signature as a private method in one of its superclasses, and there is no requirement that the return type or throws clause of such a method bear any relationship to those of the private method in the superclass.

畢竟,你只想到一個private方法被程序代碼中調用同一個班級 - 如果因爲重寫公共方法而最終被調用,那會很混亂。

2

如果你仔細想想,不能夠做到這一點是有道理的..

的原因是,你可以通過子對象四周,好像是父一(即你可以使用父類型一個TestClass實例的引用類型)。

例如

parent p = new TestClass(); 

有可能一些代碼的其他地方,它使用parent類型,並調用該方法:

例如

public static void aMethod(parent aParent){ 
    p.func(); 
} 

如果能夠減少方法然後調用aMethod(p)的知名度將不得不放棄某種運行時異常的 - 不允許這樣可以保證這不是必需的。