protected用法 - java public用法




Java中的public,protected,package-private和private有什麼區別? (16)

在Java中,是否有明確的規則來確定何時使用每個訪問修飾符,即默認(包私有), publicprotectedprivate ,同時創建classinterface以及處理繼承?


私人的

  • 方法,變量和構造函數

聲明為private的方法,變量和構造函數只能在聲明的類本身中訪問。

  • 類和接口

專用訪問修飾符是限制性最強的訪問級別。 類和接口不能是私有的。

注意

如果類中存在公共getter方法,則可以在類外部訪問聲明為private的變量。 在超類中聲明受保護的變量,方法和構造函數只能由其他包中的子類或受保護成員類的包中的任何類訪問。

受保護

  • 類和接口

受保護的訪問修飾符不能應用於類和接口。

方法,字段可以聲明為protected,但是接口中的方法和字段不能聲明為protected。

注意

受保護的訪問權限使子類有機會使用輔助方法或變量,同時防止非相關類嘗試使用它。

上市

可以從任何其他類訪問聲明為public的類,方法,構造函數,接口等。

因此,可以從屬於Java Universe的任何類訪問在公共類中聲明的字段,方法,塊。

  • 不同的包

但是,如果我們嘗試訪問的公共類位於不同的包中,則仍需要導入公共類。

由於類繼承,類的所有公共方法和變量都由其子類繼承。

默認-No關鍵字:

默認訪問修飾符意味著我們沒有為類,字段,方法等顯式聲明訪問修飾符。

  • 在同一個包中

聲明沒有任何訪問控制修飾符的變量或方法可用於同一包中的任何其他類。 接口中的字段隱式為public static final,接口中的方法默認為public。

注意

我們不能覆蓋靜態字段。如果你試圖覆蓋它,它不顯示任何錯誤,但它不起作用我們除外。

相關答案

參考鏈接

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm


Java中最容易被誤解的訪問修飾符protected 。 我們知道它與默認修飾符類似,但有一個例外,即子類可以看到它。 但是怎麼樣? 這是一個有希望澄清混淆的例子:

  • 假設我們有2個班級; FatherSon ,每個都在自己的包裝中:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • 讓我們為Father添加一個受保護的方法foo()

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
  • 方法foo()可以在4個上下文中調用:

    1. 在一個類中,該類位於定義了foo()的同一個包中( fatherpackage ):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
    2. 在子類內部,通過thissuper在當前實例上:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    3. 在類型相同的引用上:

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
      
    4. 在類型為父類的引用上,它位於包中,其中定義了foo()fatherpackage )[這可以包含在上下文中。 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
  • 以下情況無效。

    1. 在類型為父類的引用上,它位於定義了foo()的包之外fatherpackage ):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
    2. 子類包內的非子類(子類從其父類繼承受保護的成員,並使它們對非子類是私有的):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
      

官方教程可能對你有用。

            │ Class │ Package │ Subclass │ Subclass │ World
            │       │         │(same pkg)│(diff pkg)│ 
────────────┼───────┼─────────┼──────────┼──────────┼────────
public      │   +   │    +    │    +     │     +    │   +     
────────────┼───────┼─────────┼──────────┼──────────┼────────
protected   │   +   │    +    │    +     │     +    │         
────────────┼───────┼─────────┼──────────┼──────────┼────────
no modifier │   +   │    +    │    +     │          │    
────────────┼───────┼─────────┼──────────┼──────────┼────────
private     │   +   │         │          │          │    

+ : accessible
blank : not accessible

此頁面很好地描述了受保護和默認訪問修飾符

....受保護:受保護的訪問修飾符有點棘手,你可以說是默認訪問修飾符的超集。受保護的成員與默認成員相同,只要涉及相同包中的訪問權限即可。不同之處在於,受保護成員也可以被聲明成員的類的子類訪問,這些成員位於父類所在的包之外。

但是這些受保護的成員“只能通過繼承才能在程序包外部訪問”。即,您可以直接訪問其他包中存在的子類中受保護的成員,就好像該成員存在於子類本身中一樣。但是,通過使用父類的引用,無法在包外部的子類中訪問該受保護的成員。 ....


私人 :僅限課程訪問

默認值(無修飾符) :對類和包的訪問受限

受保護 :對類,包和子類的有限訪問(包內和包外)

公共 :可訪問類,包(所有)和子類......簡而言之,無處不在。


Public Protected Default和private是訪問修飾符。

它們用於封裝,或隱藏和顯示類的內容。

  1. 類可以是公共的或默認的
  2. 類成員可以是公共的,受保護的,默認的或私有的。

在類之外無法訪問私有默認只能在包中訪問。受保護的包以及任何擴展它的類。公眾對所有人開放。

通常,成員變量是私有的,但成員方法是公共的。


差異可以在已經提供的鏈接中找到,但使用哪個通常歸結為“最少知識原則”。 僅允許所需的最低可見性。


很短的

  • public :無處不在。
  • protected :可由同一個包的類和駐留在任何包中的子類訪問。
  • default(未指定修飾符):可由同一包的類訪問。
  • private :只能在同一個班級內訪問。

簡單的規則。 首先聲明一切都是私密的。 然後隨著需求的出現向公眾發展,設計需要保證。

當暴露成員時,問問自己是否暴露了表示選擇或抽象選擇。 第一個是你想要避免的東西,因為它會在實際表示中引入太多依賴,而不是它的可觀察行為。

作為一般規則,我嘗試通過子類化來避免重寫方法實現; 搞砸邏輯太容易了。 如果要覆蓋它,則聲明抽象受保護的方法。

此外,在重寫時使用@Override註釋可以防止重構時出現問題。


訪問修飾符用於限制多個級別的訪問。

公共:它基本上就像你可以從任何類訪問一樣簡單,無論它是否在同一個包中。

要訪問,如果您在同一個包中,則可以直接訪問,但如果您在另一個包中,則可以創建該類的對象。

默認值:可以從任何類包中的同一個包中訪問它。

要訪問,您可以創建該類的對象。 但是您無法在包外部訪問此變量。

受保護:您可以訪問同一個包中的變量以及任何其他包中的子類。 所以基本上它是默認+繼承的行為。

要訪問基類中定義的受保護字段,可以創建子類的對象。

私有:它可以在同一個類中訪問。

在非靜態方法中,您可以直接訪問因為引用(也在構造函數中),但要在靜態方法中訪問,您需要創建類的對象。


David的回答提供了每個訪問修飾符的含義。至於何時使用每個,我建議公開所有類和每個類的方法,以供外部使用(其API),其他一切都是私有的。

隨著時間的推移,您將了解何時將某些類包裝為私有以及何時聲明受保護以在子類中使用的某些方法。


包裝可見。默認值。不需要修飾符。

僅對班級可見(私人)。

對世界可見(公眾)。

包和所有子類(受保護)可見。

可以在不調用任何修飾符的情況下聲明變量和方法。默認示例:

String name = "john";

public int age(){
    return age;
}

私人訪問修飾符 - 私有:

聲明為private的方法,變量和構造函數只能在聲明的類本身中訪問。私有訪問修飾符是限制性最強的訪問級別。類和接口不能是私有的。

如果類中存在公共getter方法,則可以在類外部訪問聲明為private的變量。

使用private修飾符是對象封裝自身並隱藏來自外部世界的數據的主要方式。

例子:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

公共訪問修飾符 - 公共:

可以從任何其他類訪問聲明為public的類,方法,構造函數,接口等。因此,可以從屬於Java Universe的任何類訪問在公共類中聲明的字段,方法,塊。

但是,如果我們嘗試訪問的公共類位於不同的包中,則仍需要導入公共類。

由於類繼承,類的所有公共方法和變量都由其子類繼承。

例:

public void cal(){

}

受保護的訪問修飾符 - 受保護:

在超類中聲明受保護的變量,方法和構造函數只能由另一個包中的子類或受保護成員類的包中的任何類訪問。

受保護的訪問修飾符不能應用於類和接口。方法,字段可以聲明為protected,但是接口中的方法和字段不能聲明為protected。

受保護的訪問權限使子類有機會使用輔助方法或變量,同時防止非相關類嘗試使用它。

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

我經常意識到,通過創造現實世界的類比,記住任何語言的基本概念都是可能的。以下是我在Java中理解訪問修飾符的類比:

我們假設您是一所大學的學生,並且您有一位朋友將在周末來訪您。假設校園中間有一座大學創始人的大型雕像。

  • 當你把他帶到校園時,你和你朋友看到的第一件事就是這座雕像。這意味著任何走進校園的人都可以在未經大學許可的情況下觀看雕像。這使得雕像成為PUBLIC

  • 接下來,你想把你的朋友帶到你的宿舍,但為此你需要將他註冊為訪客。這意味著他獲得了進入通行證(與您的通行證相同)以進入校園內的各種建築物。這將使他的訪問卡成為受保護的

  • 您的朋友想要登錄校園WiFi,但沒有任何憑據可以登錄。他上網的唯一方法就是與他分享您的登錄信息。(請記住,每個上大學的學生也擁有這些登錄憑據)。這將使您的登錄憑據為NO MODIFIER

  • 最後,您的朋友想要閱讀您在網站上發布的學期的進度報告。但是,每個學生都有自己的個人登錄信息,可以訪問校園網站的這一部分。這將使這些憑據成為PRIVATE

希望這可以幫助!


注意:這只是對已接受答案的補充

這與Java Access Modifiers有關

Java Access修飾符

Java訪問修飾符指定哪些類可以訪問給定的類及其字段,構造函數和方法。可以為類,其構造函數,字段和方法單獨指定訪問修飾符。Java訪問修飾符有時在日常語音中稱為Java訪問說明符,但正確的名稱是Java訪問修飾符。類,字段,構造函數和方法可以具有四種不同的Java訪問修飾符之一:

  • 項目清單
  • 私人的
  • 默認(包)
  • 保護
  • 上市

控制對類成員的訪問教程:

訪問級別修飾符確定其他類是否可以使用特定字段或調用特定方法。訪問控制有兩個級別:

  • 在頂層 - public或package-private(沒有顯式修飾符)。
  • 在成員級別 - public,private,protected或package-private(無顯式修飾符)。

可以使用修飾符public聲明一個類,在這種情況下,該類對於所有類都可見。如果一個類沒有修飾符(默認值,也稱為包私有),則它只在其自己的包中可見

下表顯示了每個修飾符允許的成員訪問權限。

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ Modifier    ║ Class ║ Package ║ Subclass ║ World ║
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
║ public      ║ Y     ║ Y       ║ Y        ║ Y     ║
║ protected   ║ Y     ║ Y       ║ Y        ║ N     ║
║ no modifier ║ Y     ║ Y       ║ N        ║ N     ║
║ private     ║ Y     ║ N       ║ N        ║ N     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

第一個數據列指示類本身是否可以訪問由訪問級別定義的成員。如您所見,類始終可以訪問自己的成員。第二列指示與該類相同的包中的類(無論其父項是否有)可以訪問該成員。第三列指示在此包外聲明的類的子類是否可以訪問該成員。第四列指示是否所有類都可以訪問該成員。

訪問級別以兩種方式影響您。首先,當您使用來自其他源的類(例如Java平台中的類)時,訪問級別將確定您自己的類可以使用的這些類的哪些成員。其次,當您編寫一個類時,您需要確定每個成員變量和類中的每個方法應具有的訪問級別。


這完全是關於封裝(或者像喬菲利普斯所說的那樣,知識最少)。

從限制性最強(私有)開始,看看以後是否需要限制較少的修飾符。

我們都使用方法和成員修飾符,如private,public,...但是開發人員做的一件事就是使用包來邏輯地組織代碼。

例如:您可以將敏感的安全方法放在“安全”包中。然後放一個公共類來訪問此包中的一些安全相關代碼,但保持其他安全類包的私有性。因此,其他開發人員只能使用此包外部的公共可用類(除非他們更改修飾符)。這不是安全功能,但會指導使用。

Outside world -> Package (SecurityEntryClass ---> Package private classes)

另一個問題是,彼此依賴很多的類可能最終存在於同一個包中,如果依賴性太強,最終可能會被重構或合併。

如果恰恰相反,你將所有內容設置為公開,則不清楚應該或不應該訪問的內容,這可能會導致編寫大量的javadoc(它不會通過編譯器執行任何操作......)。


                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔   
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘    




access-modifiers