java學習筆記之——訪問權限控制



成員的訪問權限

首先先聲明一下friendly默認訪問權限,就是在類的成員變量或者成員方法在沒有被public,private,protected修飾時就是默認訪問權限。(唉,說到這裏就想起來java期末考試時老師讓建一個“友好型”的方法,我在聲明方法的時候想不出friendly怎麼拼寫,最後那裏空了一格沒寫,現在回想起來真是被機智的自己感動哭了。)

另外,需要注意一下局部變量不能用修飾符修飾,它們只能在方法內使用。

以下是幾個訪問權限控制修飾詞的訪問範圍:

本類訪問    包內訪問   包外子類訪問   包外非子類訪問

Public           Y                Y                   Y                      Y

Friendly        Y                Y                   N                     N

Protected      Y               Y                   Y                      N

Private           Y               N                  N                     N

Public 修飾的變量和方法是沒有限制包內外都可以訪問。

Friendly (就這樣寫好了,它是默認的,但我總得叫它點兒什麼)修飾的變量和方法是有包訪問權限,本包可以訪問,外包不可訪。

Protected 修飾的變量和方法也是有包訪問權限,它與friendly的

區別是,它所在類的包外子類可以繼承和訪問protected 修飾的變量和方法。

Private 除了包含該成員的類其他任何類都無法訪問該成員。

類的訪問權限

類的訪問權限僅有兩個選擇:包訪問權限(默認)和public。如果不希望對該類擁有訪問權限,可以把所有的構造器都指定爲private,從而阻止任何人創建該類的對象,但是在該類的static成員內部可以創建。

驗證代碼如下所示:

包內測試:

package cn.zjnu.edu.java2425;
class Soup1{
private Soup1(){System.out.println("用static方法創建Soup1對象並返回引用");}
public static Soup1 makeSoup(){
    return new Soup1();
}
}
class Soup2{
private Soup2(){System.out.println("通過static private成員創建Soup2對象,通過access()方法訪問");}
private static Soup2 ps1=new Soup2();
public static Soup2 access(){
	return ps1;
}
}
class Soup3{
	Soup3(){
		System.out.println("包內可以訪問默認類,包外不能訪問");
	}
}
public class Lunch {
	void testPrivate(){
		//Soup1 soup=new Soup1();不能這樣的,報錯信息“The constructor Soup1() is not visible”
	}
	void testStatic(){
		Soup1 soup=Soup1.makeSoup();
	}
	void tastSingleton(){
	  Soup2.access();
	}
	public Lunch(){//這裏構造器也要是public才能進行包外訪問
		System.out.println("包內外都可以訪問public類");
	}
	public static void main(String arg[]){
		Lunch l1=new Lunch();
		l1.testStatic();
		l1.tastSingleton(); 
	    Soup3 s=new Soup3();
	}
}

運行結果:

包內外都可以訪問public類

用static方法創建Soup1對象並返回引用

通過static private成員創建Soup2對象,通過access()方法訪問

包內可以訪問默認類,包外不能訪問

包外測試:

package cn.zjnu.practise;
import cn.zjnu.edu.java2425.Lunch;
public class TestClass {
	public static void main(String[] args) {
		Lunch l=new Lunch();
        //Soup3 s3=new Soup3();報錯,包外不能訪問Soup3
	}
}

運行結果:

包內外都可以訪問public類

在代碼中

public static Soup1 makeSoup(){

return new Soup1();

}

Soup1中創建一個static方法,它創建一個新的Soup1對象並返回一個對它的引用。

Soup2類的對象是作爲Soup2的一個static private成員而創建的,所以有且僅有一個,並且除非是通過public方法access(),否則是無法訪問到它的。

對於public類:

  • 每個編譯單元都只有一個public類,有一個以上的public類,編譯器會報錯。
  • Public類的名稱必須與含有該編譯單元的文件名相匹配,包括大小寫。
  • 編譯單元內完全不帶public類也是可能的,在這種情況下可以隨意對文件命名。

類訪問權限+成員訪問權限:(取兩者最小訪問權限)

Public類的成員:

本類訪問    包內訪問   包外子類訪問   包外非子類訪問

Public              Y                Y                      Y                   Y

Friendly          Y                Y                      N                   N

Protected       Y                Y                      Y                    N

Private            Y                N                     N                   N

默認類的成員:

本類訪問    包內訪問   包外子類訪問   包外非子類訪問

Public              Y             Y                   N                      N

Friendly          Y             Y                    N                      N

Protected       Y             Y                    N                      N

Private            Y             N                   N                      N

驗證代碼如下所示:

1、創建一個默認類和一個public類

package cn.zjnu.edu.java2425;
 class Sub{
	 Sub(){
		System.out.println("默認類:");
	}
	 public void PublicTest(){
			System.out.println("public方法可以跨包訪問");
		}
		protected void ProtectedTest(){
			System.out.println("protected方法可以被包內其他類訪問,可以被包外子類訪問");
		}
		void FriendlyTest(){
			System.out.println("默認方法只能包內訪問");
		}	
	    private void PrivateTest(){
		System.out.println("默認類獨享的private方法");
	}
}
public class Sub1 {
     public Sub1(){
		System.out.println("public類:");
	}
public void PublicTest(){
	System.out.println("public方法可以跨包訪問");
}
protected void ProtectedTest(){
	System.out.println("protected方法可以被包內其他類訪問,可以被包外子類訪問");
}
void FriendlyTest(){
	System.out.println("默認方法只能包內訪問");
}
private void PrivateTest(){
	System.out.println("本類獨享的private方法");
}	
public static void main(String[] args) {
	System.out.println("類內部private方法測試:");
	Sub1 s1=new Sub1();
	s1.PrivateTest();
	Sub s=new Sub();
	//s.PrivateTest();private類不能被其他任何類訪問
}
}

運行結果:

類內部private方法測試:

public類:

本類獨享的private方法

默認類:

2、包內測試:

package cn.zjnu.edu.java2425;
public class Son {
	public static void main(String[] args) {
		System.out.println("包內測試:");
		Sub1 s1=new Sub1();
		s1.PublicTest();
		s1.ProtectedTest();
	    s1.FriendlyTest();
	    //s1.PrivateTest();private類不能被其他任何類訪問
        Sub s=new Sub();
        s.PublicTest();
        s.ProtectedTest();
        s.FriendlyTest();
        //s.PrivateTest();private類不能被其他任何類訪問
	}
}

運行結果:

包內測試:

public類:

public方法可以跨包訪問

protected方法可以被包內其他類訪問,可以被包外子類訪問

默認方法只能包內訪問

默認類:

public方法可以跨包訪問

protected方法可以被包內其他類訪問,可以被包外子類訪問

默認方法只能包內訪問

3、包外其他類測試:

package cn.zjnu.edu.javase;
import cn.zjnu.edu.java2425.Sub1;
public class Son1 {
	public static void main(String[] args) {
		System.out.println("包外其他類測試:");
		Sub1 s1=new Sub1();
		s1.PublicTest();
		//s1.ProtectedTest();包外其他類protected方法不能被訪問
	    //s1.FriendlyTest();包外其他類friendly方法不能被訪問
	    //s1.PrivateTest();private類不能被其他任何類訪問
        //Sub s=new Sub();包外默認類不能被訪問
	}
}

運行結果:

包外其他類測試:

public類:

public方法可以跨包訪問

4、包外子類測試:

package cn.zjnu.edu.javase;
import cn.zjnu.edu.java2425.Sub1;
public class Son2 extends Sub1{//包外子類測試
	public static void main(String[] args) {
		System.out.println("包外子類測試:");
		Son2 son=new Son2();
		son.PublicTest();
		son.ProtectedTest();//包外父類protected方法能被包外子類訪問
		//son.FriendlyTest();包外父類friendly方法不能被包外子類訪問
		//s1.PrivateTest();private類不能被其他任何類訪問
	}
}

運行結果:

包外子類測試:

public類:

public方法可以跨包訪問

protected方法可以被包內其他類訪問,可以被包外子類訪問

發佈了33 篇原創文章 · 獲贊 33 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章