《Java從小白到大牛》紙質版已經上架了!!!
html
Java面向對象的封裝性是經過對成員變量和方法進行訪問控制實現的,訪問控制分爲4個等級:私有、默認、保護和公有,具體規則如表10-1所示。java
表 101 Java類成員的訪問控制app
能否直接訪問控制等級 | 同一個類 | 同一個包 | 不一樣包的子類 | 不一樣包非子類 |
---|---|---|---|---|
私有 | Yes | |||
默認 | Yes | Yes | ||
保護 | Yes | Yes | Yes | |
公有 | Yes | Yes | Yes | Yes |
下面詳細解釋一下這4種訪問級別。ide
私有級別的關鍵字是private,私有級別的成員變量和方法只能在其所在類的內部自由使用,在其餘的類中則不容許直接訪問。私有級別限制性最高。私有級別示例代碼以下:ui
// PrivateClass.java文件 package com.a51work6; public class PrivateClass { ① private int x; ② public PrivateClass() { ③ x = 100; } private void printX() { ④ System.out.println("Value Of x is" + x); } } // HelloWorld.java文件調用PrivateClass package com.a51work6; public class HelloWorld { public static void main(String[] args) { PrivateClass p; p = new PrivateClass(); //編譯錯誤,PrivateClass中的方法 printX()不可見 p.printX(); ⑤ } }
上述代碼第①行聲明PrivateClass類,其中的代碼第②行是聲明私有實例變量x,代碼第③行是聲明公有的構造方法,構造方法將在第12章詳細介紹。代碼第④行聲明私有實例方法。rest
HelloWorld類中代碼第⑤行會有編譯錯誤,由於PrivateClass中printX()的方法是私有方法。code
默認級別沒有關鍵字,也就是沒有訪問修飾符,默認級別的成員變量和方法,能夠在其所在類內部和同一個包的其餘類中被直接訪問,但在不一樣包的類中則不容許直接訪問。視頻
默認級別示例代碼以下:htm
// DefaultClass.java文件 package com.a51work6; public class DefaultClass { int x; ① public DefaultClass() { x = 100; } void printX() { ② System.out.println("Value Of x is" + x); } }
上述代碼第①行的x變量前沒有訪問限制修飾符,代碼第②行的方法也是沒有訪問限制修飾符。它們的訪問級別都有默認訪問級別。對象
在相同包(com.a51work6)中調用DefaultClass類代碼以下:
// com.a51work6包中HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { DefaultClass p; p = new DefaultClass(); p.printX(); } }
默認訪問級別能夠在同一包中訪問,上述代碼能夠編譯經過。
在不一樣的包中調用DefaultClass類代碼以下:
// 默認包中HelloWorld.java文件 import com.a51work6.DefaultClass; public class HelloWorld { public static void main(String[] args) { DefaultClass p; p = new DefaultClass(); // 編譯錯誤,DefaultClass中的方法 printX()不可見 p.printX(); } }
該HelloWorld.java文件與DefaultClass類不在同一個包中,printX()是默認訪問級別,因此p.printX()方法沒法編譯經過。
公有級別的關鍵字是public,公有級別的成員變量和方法能夠在任何場合被直接訪問,是最寬鬆的一種訪問控制等級。
公有級別示例代碼以下:
// PublicClass.java文件 package com.a51work6; public class PublicClass { public int x; ① public PublicClass() { x = 100; } public void printX() { ② System.out.println("Value Of x is" + x); } }
上述代碼第①行的x變量是公有級別,代碼第②行的方法也是公有級別。調用PublicClass類代碼以下:
// 默認包中HelloWorld.java文件 import com.a51work6.PublicClass; public class HelloWorld { public static void main(String[] args) { PublicClass p; p = new PublicClass(); p.printX(); } }
該HelloWorld.java文件與PublicClass類不在同一個包中,能夠公有的printX()方法。
保護級別的關鍵字是protected,保護級別在同一包中徹底與默認訪問級別同樣,可是不一樣包中子類可以繼承父類中的protected變量和方法,這就是所謂的保護級別,「保護」就是保護某個類的子類都能繼承該類的變量和方法。
保護級別示例代碼以下:
// ProtectedClass.java文件 package com.a51work6; public class ProtectedClass { protected int x; ① public ProtectedClass() { x = 100; } protected void printX() { ② System.out.println("Value Of x is " + x); } }
上述代碼第①行的x變量是保護級別,代碼第②行的方法也是保護級別。
在相同包(com.a51work6)中調用ProtectedClass類代碼以下:
// 默認包中HelloWorld.java文件 package com.a51work6; import com.a51work6.ProtectedClass; public class HelloWorld { public static void main(String[] args) { ProtectedClass p; p = new ProtectedClass(); // 同一包中能夠直接訪問ProtectedClass中的方法 printX() p.printX(); } }
同一包中保護訪問級別與默認訪問級別同樣,能夠直接訪問ProtectedClass的printX()方法,上述代碼能夠編譯經過。
在不一樣的包中調用ProtectedClass類代碼以下:
// 默認包中HelloWorld.java文件 import com.a51work6.ProtectedClass; public class HelloWorld { public static void main(String[] args) { ProtectedClass p; p = new ProtectedClass(); // 編譯錯誤,不一樣包中不能直接訪問保護方法printX() p.printX(); } }
該HelloWorld.java文件與ProtectedClass類不在同一個包中,不一樣包中不能直接訪問保護方法printX(),因此p.printX()方法沒法編譯經過。
在不一樣的包中繼承ProtectedClass類代碼以下:
// 默認包中SubClass.java文件 import com.a51work6.ProtectedClass; public class SubClass extends ProtectedClass { void display() { //printX()方法是從父類繼承過來 printX(); ① //x實例變量是從父類繼承過來 System.out.println(x); ② } }
不一樣包中SubClass從ProtectedClass類繼承了printX()方法和x實例變量。代碼第①行是調用從父類繼承下來的方法,代碼第②行是調用從父類繼承下來的實例變量。
提示 訪問成員有兩種方式:一種是調用,即經過類或對象調用它的成員,如p.printX()語句;另外一種是繼承,即子類繼承父類的成員變量和方法。
提示 訪問類成員時,在能知足使用的前提下,應儘可能限制類中成員的可見性,訪問級別順序是:私有級別→默認級別→保護級別→公有級別。
靜態變量和靜態方法
有一個Account(銀行帳戶)類,假設它有三個成員變量:amount(帳戶金額)、interestRate(利率)和owner(帳戶名)。在這三個成員變量中,amount和owner會因人而異,對於不一樣的帳戶這些內容是不一樣的,而全部帳戶的interestRate都是相同的。
amount和owner成員變量與帳戶個體有關,稱爲「實例變量」,interestRate成員變量與個體無關,或者說是全部帳戶個體共享的,這種變量稱爲「靜態變量」或「類變量」。
靜態變量和靜態方法示例代碼以下:
// Account.java文件 package com.a51work6; public class Account { // 實例變量帳戶金額 double amount = 0.0; ① // 實例變量帳戶名 String owner; ② // 靜態變量利率 static double interestRate = 0.0668; ③ // 靜態方法 public static double interestBy(double amt) { ④ //靜態方法能夠訪問靜態變量和其餘靜態方法 return interestRate * amt; ⑤ } // 實例方法 public String messageWith(double amt) { ⑥ //實例方法能夠訪問實例變量、實例方法、靜態變量和靜態方法 double interest = Account.interestBy(amt); ⑦ StringBuilder sb = new StringBuilder(); // 拼接字符串 sb.append(owner).append("的利息是").append(interest); // 返回字符串 return sb.toString(); } }
static修飾的成員變量是靜態變量,見代碼第③行。staitc修飾的方法是靜態方法,見代碼第④行。相反,沒有static修飾的成員變量是實例變量,見代碼第①行和第②行;沒有staitc修飾的方法是實例方法,見代碼第⑥行。
注意 靜態方法能夠訪問靜態變量和其餘靜態方法,例如訪問代碼第⑤行中的interestRate靜態變量。實例方法能夠訪問實例變量、其餘實例方法、靜態變量和靜態方法,例如訪問代碼第⑦行interestBy靜態方法。
調用Account代碼以下:
// HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { // 訪問靜態變量 System.out.println(Account.interestRate); ① // 訪問靜態方法 System.out.println(Account.interestBy(1000)); ② Account myAccount = new Account(); // 訪問實例變量 myAccount.amount = 1000000; ③ myAccount.owner = "Tony"; ④ // 訪問實例方法 System.out.println(myAccount.messageWith(1000)); ⑤ // 經過實例訪問靜態變量 System.out.println(myAccount.interestRate); ⑥ } }
調用靜態變量或靜態方法時,能夠經過類名或實例名調用,代碼第①行Account.interestRate經過類名調用靜態變量,代碼第②行Account.interestBy(1000)是經過類名調用靜態方法。代碼第⑥行是經過實例調用靜態變量。
前面介紹的靜態變量interestRate,能夠在聲明同時初始化,以下代碼所示。
public class Account { // 靜態變量利率 static double interestRate = 0.0668; ... }
若是初始化靜態變量不是簡單常量,須要進行計算才能初始化,可使用靜態(static)代碼塊,靜態代碼塊在類第一次加載時執行,並只執行一次。示例代碼以下:
// Account.java文件 package com.a51work6; public class Account { // 實例變量帳戶金額 double amount = 0.0; // 實例變量帳戶名 String owner; // 靜態變量利率 static double interestRate; // 靜態方法 public static double interestBy(double amt) { // 靜態方法能夠訪問靜態變量和其餘靜態方法 return interestRate * amt; } // 靜態代碼塊 static { ① System.out.println("靜態代碼塊被調用..."); // 初始化靜態變量 interestRate = 0.0668; ② } }
上述代碼第①行是靜態代碼塊,在靜態代碼塊中能夠初始化靜態變量,見代碼第②行,也能夠調用靜態方法。
調用Account代碼以下:
// HelloWorld.java文件 package com.a51work6; public class HelloWorld { public static void main(String[] args) { Account myAccount = new Account(); ① // 訪問靜態變量 System.out.println(Account.interestRate); ② // 訪問靜態方法 System.out.println(Account.interestBy(1000)); } }
Account靜態代碼塊是在第一次加載Account類時調用。上述代碼第①行是第一次使用Account類,此時會調用靜態代碼塊。
本章主要介紹了面向對象基礎知識。首先介紹了面向對象一些基本概念,面向對象三個基本特性。而後介紹了類、包、方法重載和訪問控制。最後介紹了靜態變量、靜態方法和靜態代碼塊。
http://edu.51cto.com/topic/1246.html
http://www.zhijieketang.com/group/5