java訪問控制符詳解

使用訪問控制符

java提供了3個訪問控制符:private、protected和public,分別代表3個訪問控制級別,另外還有一個不加任何訪問控制符的訪問控制級別,提供了4個訪問控制級別。

訪問權限由小到大:private——>default——>protected——>public
注意沒有default這個關鍵字,不寫則默認代表此訪問權限

private(當前類訪問權限)

如果類裏的一個成員(包括Field、方法和構造器等)使用private訪問控制符來修飾,則這個成員只能在當前類的內部被訪問。很顯然,這個訪問控制符用於修飾Field最合適,使用它來修飾Field就可以把Field隱藏在該類的內部。

這個概念大家應該沒什麼異議

default(包訪問權限)

如果類裏的一個成員(包括Field、方法和構造器等)或者一個外部類不使用任何控制符修飾,我們就稱它是包訪問權限,default訪問控制的成員或外部類可以被相同包下的其他類訪問。

何爲包 package
java引入了包(package)機制,提供了類的多層命名空間,用於解決類的命名衝突、類文件管理等問題。

java規定:位於包中的類,在文件系統中也必須有與包名層次相同的目錄結構
假設某個應用中包含兩個Hello類,java通過引入包機制來區分兩個不同的Hello類。不僅如此,這兩個Hello類還對應兩個Hello.class文件,它們在文件系統中也必須分開存放纔不會引起衝突。

所以java的包機制需要兩個方面保證:
1.源文件裏使用package語句指定包名;
2.class文件必須放在對應的路徑下。

package語句必須作爲源文件的第一條非註釋性語句,一個源文件只能指定一個包,即只能包含一條package語句,該源文件中可以定義多個類,則這些類將全部位於該包下

java默認爲所有源文件導入java.lang包下的所有類,因此在java程序中使用String、System類時都無須使用import語句來導入這些類

也就是說java中要使用其他包中類時需要導入對應類的包或者指定該類的全限定名,如果是在同一包下則可以直接使用同一包下的類

再回到default包訪問權限問題上,就拿class來說
先在com.sunrise.eHealth.day0521.other包下定義一個HelloWorld 類,該類的權限爲default

package com.sunrise.eHealth.day0521.other;

class HelloWorld {
}

在這裏插入圖片描述
在com.sunrise.eHealth.day0521包下Demo1類中引入HelloWorld,發現導入了HelloWorld 類所在包,仍然報錯,即驗證了default權限的類不能在其它包中使用

package com.sunrise.eHealth.day0521.other;

public class Dog {

    public static void main(String[] args) {
        HelloWorld hw = new HelloWorld();
    }

}

在相同包下則可以使用HelloWorld類,並且不用import相應包

protected(子類訪問權限)

如果一個成員(包括Field、方法和構造器等)使用protected訪問控制符修飾,那麼這個成員既可以被同一個包中的其他類訪問,也可以被不同包中的子類訪問。在通常情況下,如果使用protected來修飾一個方法,通常是希望其子類來重寫這個方法。

package com.sunrise.eHealth.day0521.other;

public class Animal {

    protected void info(){
        System.out.println("i am animal");
    }

}

由於外部類的訪問控制符只能是public 或者 default(不加訪問控制符),不能使用private和protected修飾,因爲外部類沒有處於任何類的內部,也就沒有所在類的內部、所在類的子類兩個範圍,所以上面代碼在方法前加上protected訪問控制符,在相同包下調用info方法顯然是沒有問題的,但是在其它包下則無法調用info方法
在這裏插入圖片描述
除非該類繼承Animal,然後通過子類去訪問info方法

public class Demo2 {

    public static void main(String[] args) {
        Monkey m = new Monkey();
        m.eat();

    }

}

class Monkey extends Animal{

    public void eat(){
        this.info();
    }

}

有此可以看出Monkey 子類可以訪問info方法,通常情況下,如果使用protected來修飾一個方法,通常是希望其子類來重寫這個方法。
有人可能要說希望子類重寫何不將父類方法定義爲abstract抽象方法呢?
方法定義爲abstract是強制讓子類重寫,而且父類變爲抽象類或者接口,不能直接使用父類,也限制了子類必須要重寫該方法,只能說側重點不一樣吧

public(公共訪問權限)

這是一個最寬鬆的訪問控制級別,如果一個成員(包括Field、方法和構造器)或者一個外部類使用public訪問控制符修飾,那麼這個成員或外部類就可以被所有類訪問,不管訪問類和被訪問類是否處於同一個包中,是否具有父子關係。

注意:

要使用不同包下的類,必須要先import該類所在包(不導入包則要寫全限定名),然後再看訪問控制權限,如果是public修飾的類則可以訪問,如果是default即沒有public修飾的類則不可以訪問(即使已經導入了該類所在包)

附上訪問控制級別圖

在這裏插入圖片描述

如果一個java源文件裏定義的所有類都沒有使用public修飾,則這個java源文件的文件名可以是一切合法的文件名;但如果一個java源文件裏定義了一個public修飾的類,則這個源文件的文件名必須與public修飾的類的類名相同

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章