許可權修飾符的訪問範圍
許可權修飾符的訪問範圍 下面我們進行測試:
1.建立兩個包,取名為com.syc.test和com.syc.input,然後在com.syc.test下建立Test類、Woman類,com.syc.input下建立People類 2.編寫程式碼。people.java檔案的內容如下:
package com.syc.input;
public class People {
}
class Man{
}
Test類的內容如下:
package com.syc.test;
import com.syc.input.People;
public class Test {
public static void main(String[] args){
new People();//跨包時需要導包
// new Man();//錯誤,表示default修飾的類不能跨包訪問
new Woman();
}
}
Woman類的內容如下:
package com.syc.test;
class Woman {
}
3.測試並總結:我們用Test類中的main方法進行測試,發現建立People物件是可以直接new出來的(Public全域性訪問),但是Man物件卻無法建立,而Woman物件也是可以new出來(default只能在同包中訪問)。
二、修飾成員
許可權修飾符修飾成員的訪問範圍如下圖所示:
我們按照許可權由小到大的順序來測試修飾符修飾成員的情況。
1.測試private
我們新建立一個專案,然後建立包com.syc.test,在其中新建一個類People
編寫People的程式碼如下:
package com.syc.test;
public class People {
//訪問許可權由小到大定義成員變數
private int a = 10;
int b = 20;
protected int c = 30;
public int d = 40;
//訪問許可權由小到大定義成員方法
private void fun1(){
}
void fun2(){
}
protected void fun3(){
}
public void fun4(){
}
public static void main(String[] args) {
//本類當中訪問成員變數和成員方法,先建立這個類的物件
People p = new People();
System.out.println(p.a);//私有的許可權最低的都能訪問,其他許可權高的一定能訪問
p.fun1();
}
}
可以看到在本類中,許可權最小的都能訪問到,其他三個就必定能夠訪問了。
2.測試default
我們繼續在com.syc.test包中建立新的類Test,然後對成員變數進行測試,發現在使用p.只彈出了bcd,可見私有成員a無法脫離其所屬類進行訪問。
Test類的程式碼如下:
package com.syc.test;
public class Test {
public static void main(String[] args) {
People p = new People();
// System.out.println(p.a);//提示錯誤,private修飾的成員不能在其類外訪問到
System.out.println(p.b);
p.fun2();
}
}
當我們跨包時,只能檢視到public所修飾的成員(此時沒有繼承):
3.測試protected
protected修飾的成員能在本類,同包,子類中被訪問。
我們在com.syc.input中新建Student類,使這個類繼承自People,然後我們可以看到能訪問到父類的protected 成員c。
public就不用說了,全域性能訪問,如上上圖(未繼承時)能訪問到public成員d。
三、修飾構造器
許可權修飾符修飾構造器的訪問範圍與修飾成員時候訪問範圍相同。
1.測試private
和測試成員一樣,我們新建一個專案,然後建立com.syc.test包,在其中新增People類,然後新增四個構造器(需要新增不同型別的引數來對構造器過載),並在本類中用main方法進行測試,發現四個構造器均能使用。
package com.syc.Test;
public class People {
private People(){
}
People(int a){
}
protected People(char c){
}
public People(String s){
}
public static void main(String[] args) {
new People();
new People(1);
new People('c');
new People("syc");
}
}
2.測試default
我們在com.syc.Test包下新建Test類,發現不能訪問無參的私有構造器(private People(){})。
3.測試protected
protected修飾構造器時訪問範圍同修飾成員相同,都是本類,同包和其子類,但不同的是子類繼承父類,構造器不能被繼承。
(1)同包下測試:
我們在com.syc.Test包下,新建Teacher類,繼承自People類,如圖所示,會提示錯誤:在com.syc.Test.People中沒有預設的構造器,要我們建立構造器來匹配父類。為什麼會有這個提示呢?因為在我們的父類People中“沒有預設構造器”。(無參構造器被私有化,外部類無法訪問,其他三個構造器又不能被子類繼承)
解決方法有兩個:
方法一:將無參構造器公有化,即將 private People(){ }這個構造器改為public People(){ },此時我們在new Teacher()的時候,會先呼叫父類的無參構造器,然後呼叫子類的無參構造器。做如下修改:
People類
package com.syc.Test;
public class People {
public People(){
System.out.println("公有構造器");
}
People(int a){
}
...
Teacher類
package com.syc.Test;
public class Teacher extends People {
Teacher(){
System.out.println("預設構造器");
}
}
測試類中我們測試new Teacher();的結果如下:
說明:在呼叫子類的預設構造器的時候會先呼叫父類的預設構造器(沒有用super關鍵字指定構造器情況),相當於在Teacher()構造器的第一行有一行隱形的super();語句。
方法二:不修改無參構造器的許可權修飾符,我們建立子類的構造器,此時我們可以看到,能建立的構造器有三個。
此時,Teacher類的構造器可以是如下所示:
People類
package com.syc.Test;
public class People {
public People(){
System.out.println("公有構造器");
}
People(int a){
}
...
Teacher類
package com.syc.Test;
public class Teacher extends People {
Teacher(){
System.out.println("預設構造器");
}
}
(2)跨包下測試:
若我們建立一個新包com.syc.input,並在其中建立Student類,使其繼承People類,那麼此時能建立的子類構造器只有兩個(父類中用protected與public修飾的構造器)
這個Student類的構造器便是下面這樣的:
package com.syc.input;
import com.syc.Test.People;
public class Student extends People {
protected Student(char c) {
super(c);
}
public Student(String s) {
super(s);
}
}
4.測試public
我們新建一個包com.syc.input,也建立一個類Test,此時在main方法中測試,發現只能訪問public方法修飾的構造器(public People(String s){})