2010-09-07 68 views
15

爲什麼受保護的成員允許進入最終課程?爲什麼在最終的java類中允許保護成員?

不應該是編譯時錯誤嗎?

編輯:正如人們已經指出的,您可以通過使用默認修飾符來獲得相同的包訪問權限。它應該以完全相同的方式運行,因爲protected只是default +子類,而最終修飾符明確地拒絕子類化,所以我認爲答案不僅僅是提供相同的包訪問。

+0

問題的一個變體是仍然有效:爲什麼我們可以有私有靜態最後的方法呢? 「私人」意味着「最終」以及「靜態」,對吧?它不是多餘的嗎? – gawi 2010-09-07 18:11:42

+0

@gawi:我不知道如何解釋你的評論,但'private'當然不意味着'static' /'final'。 – BalusC 2010-09-07 18:38:03

+0

@gawi:私有隱含着非虛擬的,而不是靜態的,並且說「private隱含final」是沒有意義的,因爲「final」只對繼承方法有意義。我同意,因爲我無法找到在私人方法聲明中使用「final」的有效理由。 – 2010-09-07 18:51:18

回答

17

protected修飾符是重寫從基類protected方法方法所需的時間,沒有那些成員暴露於public

一般來說,你可以引入很多不必要的規則來取締不合理的組合(例如protected static),但它沒有多大幫助。你不能取締愚蠢。

+0

啊,好的,因爲你不能減少可見度使它們成爲默認或私人(這可能是最終課程中的目標),所以你可以讓它們保護或暴露它們儘管在這種情況下使它們默認不會降低可見性(因爲不可能有子類化),所以恕我直言,編譯器應該ld停止抱怨。 – 2010-09-07 18:23:34

+0

是的。我應該說你可以讓他們「公開」,但你不想。實際上,如果你在不同的軟件包中覆蓋,'protected'特有的行爲。我不是「保護」的粉絲。 – 2010-09-07 18:29:16

+0

好點,方法也是成員!堅實的反例。 – 2010-09-07 18:40:11

14

因爲受保護的成員可以被同一包中的其他類以及子類訪問。

+6

當然如此,但如果情況如此,使用默認(包)訪問得到相同的結果,所以它仍然可能是編譯錯誤。我認爲這只是更多的證據,表明他們應該將子類可見性和包/內部類可見性保持爲完全獨立的概念。他們是誰來告訴我,如果一個子類具有可見性,包還必須? – 2010-09-07 18:06:36

+0

@Mark:是的,顯然沒有想象的那麼好。 – skaffman 2010-09-07 18:08:57

+0

「受保護的成員可以被同一包中的其他類訪問」:O真的嗎?!我認爲這是私人包裝的目的? – 2010-09-07 18:11:21

9

受保護的修飾符還允許在同一個包中訪問,而不僅僅是子類。所以在最後一堂課上它並不完全沒有意義。

+0

30秒太slooooooooo :(: – Affe 2010-09-07 18:01:45

0

你可以爭辯說,但沒有任何真正的傷害。非最終類也可能有一個受保護的成員,但沒有子類,它也不會打擾任何人。

+2

事情可以被證明無用的編譯錯誤(警告會更好)不是因爲他們直接「打擾」或「傷害」任何人/任何東西,而是因爲有非常高的可能性它是一個程序員的錯誤/錯字 – 2010-09-07 18:42:48

+0

你怎麼能證明它是無用的?將最終的類改爲非final類甚至不會破壞二進制兼容性。 – irreputable 2010-09-07 19:55:14

6

protected成員可以通過同一個包的類訪問這裏所述的參數是有效的,但在這種情況下protected變成等於默認可見性(包私有),並保持這個問題 - 爲什麼都是允許的。

我猜兩兩件事:

  • 沒有必要禁止其
  • 一類可暫時由final,在外觀設計作出決定。一個人不應該去改變所有的可視性修飾符他每次添加或刪除final
+2

+1:但我驚訝地發現「錯誤」答案的速度有多快。它是否告訴我們關於平均知識的一些知識? – BalusC 2010-09-07 18:14:18

-1
package p; 

import java.sql.Connection; 

public final class ProtectedTest { 
    String currentUser; 
    Connection con = null; 

    protected Object ProtectedMethod(){ 
     return new Object(); 
    } 
    public ProtectedTest(){ 
    } 
    public ProtectedTest(String currentUser){ 
     this.currentUser = currentUser; 
    } 
} 

package p; 

public class CallProtectedTest { 
    public void CallProtectedTestMethod() { 
     System.out.println("CallProtectedTestMethod called :::::::::::::::::"); 
     ProtectedTest p = new ProtectedTest(); 
     Object obj = p.ProtectedMethod(); 
     System.out.println("obj >>>>>>>>>>>>>>>>>>>>>>>"+obj); 
    } 
} 

package p1; 

import p.CallProtectedTest; 

public class CallProtectedTestFromp2 { 
    public void CallProtectedTestFromp2Method(){ 
     CallProtectedTest cpt = new CallProtectedTest(); 
     cpt.CallProtectedTestMethod(); 
    } 

    public static void main(String[] args) { 
     CallProtectedTestFromp2 cptf2 = new CallProtectedTestFromp2(); 
     cptf2.CallProtectedTestFromp2Method(); 
    } 
} 
+2

也許有些解釋? – cheesemacfly 2013-04-04 19:14:19

相關問題