成員的訪問權限
首先先聲明一下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方法可以被包內其他類訪問,可以被包外子類訪問