《Java從小白到大?!分?0章 面向?qū)ο蠡A(chǔ)(下)

《Java從小白到大?!芳堎|(zhì)版已經(jīng)上架了?。。?/p>

Java從小白到大牛書(shū)皮

封裝性與訪(fǎng)問(wèn)控制

Java面向?qū)ο蟮姆庋b性是通過(guò)對(duì)成員變量和方法進(jìn)行訪(fǎng)問(wèn)控制實(shí)現(xiàn)的,訪(fǎng)問(wèn)控制分為4個(gè)等級(jí):私有、默認(rèn)、保護(hù)和公有,具體規(guī)則如表10-1所示。

表 101 Java類(lèi)成員的訪(fǎng)問(wèn)控制

可否直接訪(fǎng)問(wèn)控制等級(jí) 同一個(gè)類(lèi) 同一個(gè)包 不同包的子類(lèi) 不同包非子類(lèi)
私有 Yes
默認(rèn) Yes Yes
保護(hù) Yes Yes Yes
公有 Yes Yes Yes Yes

下面詳細(xì)解釋一下這4種訪(fǎng)問(wèn)級(jí)別。

私有級(jí)別 {#-0}

私有級(jí)別的關(guān)鍵字是private,私有級(jí)別的成員變量和方法只能在其所在類(lèi)的內(nèi)部自由使用,在其他的類(lèi)中則不允許直接訪(fǎng)問(wèn)。私有級(jí)別限制性最高。私有級(jí)別示例代碼如下:

// 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文件調(diào)用PrivateClass

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

PrivateClass p;

p = new PrivateClass();

//編譯錯(cuò)誤,PrivateClass中的方法 printX()不可見(jiàn)

p.printX(); ⑤

}

}

上述代碼第①行聲明PrivateClass類(lèi),其中的代碼第②行是聲明私有實(shí)例變量x,代碼第③行是聲明公有的構(gòu)造方法,構(gòu)造方法將在第12章詳細(xì)介紹。代碼第④行聲明私有實(shí)例方法。

HelloWorld類(lèi)中代碼第⑤行會(huì)有編譯錯(cuò)誤,因?yàn)镻rivateClass中printX()的方法是私有方法。

默認(rèn)級(jí)別 {#-1}

默認(rèn)級(jí)別沒(méi)有關(guān)鍵字,也就是沒(méi)有訪(fǎng)問(wèn)修飾符,默認(rèn)級(jí)別的成員變量和方法,可以在其所在類(lèi)內(nèi)部和同一個(gè)包的其他類(lèi)中被直接訪(fǎng)問(wèn),但在不同包的類(lèi)中則不允許直接訪(fǎng)問(wèn)。

默認(rèn)級(jí)別示例代碼如下:

// 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變量前沒(méi)有訪(fǎng)問(wèn)限制修飾符,代碼第②行的方法也是沒(méi)有訪(fǎng)問(wèn)限制修飾符。它們的訪(fǎng)問(wèn)級(jí)別都有默認(rèn)訪(fǎng)問(wèn)級(jí)別。

在相同包(com.a51work6)中調(diào)用DefaultClass類(lèi)代碼如下:

// com.a51work6包中HelloWorld.java文件

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

DefaultClass p;

p = new DefaultClass();

p.printX();

}

}

默認(rèn)訪(fǎng)問(wèn)級(jí)別可以在同一包中訪(fǎng)問(wèn),上述代碼可以編譯通過(guò)。

在不同的包中調(diào)用DefaultClass類(lèi)代碼如下:

// 默認(rèn)包中HelloWorld.java文件

import com.a51work6.DefaultClass;

public class HelloWorld {

public static void main(String[] args) {

DefaultClass p;

p = new DefaultClass();

// 編譯錯(cuò)誤,DefaultClass中的方法 printX()不可見(jiàn)

p.printX();

}

}

該HelloWorld.java文件與DefaultClass類(lèi)不在同一個(gè)包中,printX()是默認(rèn)訪(fǎng)問(wèn)級(jí)別,所以p.printX()方法無(wú)法編譯通過(guò)。

公有級(jí)別 {#-2}

公有級(jí)別的關(guān)鍵字是public,公有級(jí)別的成員變量和方法可以在任何場(chǎng)合被直接訪(fǎng)問(wèn),是最寬松的一種訪(fǎng)問(wèn)控制等級(jí)。

公有級(jí)別示例代碼如下:

// 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變量是公有級(jí)別,代碼第②行的方法也是公有級(jí)別。調(diào)用PublicClass類(lèi)代碼如下:

// 默認(rèn)包中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類(lèi)不在同一個(gè)包中,可以公有的printX()方法。

保護(hù)級(jí)別 {#-3}

保護(hù)級(jí)別的關(guān)鍵字是protected,保護(hù)級(jí)別在同一包中完全與默認(rèn)訪(fǎng)問(wèn)級(jí)別一樣,但是不同包中子類(lèi)能夠繼承父類(lèi)中的protected變量和方法,這就是所謂的保護(hù)級(jí)別,“保護(hù)”就是保護(hù)某個(gè)類(lèi)的子類(lèi)都能繼承該類(lèi)的變量和方法。

保護(hù)級(jí)別示例代碼如下:

// 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變量是保護(hù)級(jí)別,代碼第②行的方法也是保護(hù)級(jí)別。

在相同包(com.a51work6)中調(diào)用ProtectedClass類(lèi)代碼如下:

// 默認(rèn)包中HelloWorld.java文件

package com.a51work6;

import com.a51work6.ProtectedClass;

public class HelloWorld {

public static void main(String[] args) {

ProtectedClass p;

p = new ProtectedClass();

// 同一包中可以直接訪(fǎng)問(wèn)ProtectedClass中的方法 printX()

p.printX();

}

}

同一包中保護(hù)訪(fǎng)問(wèn)級(jí)別與默認(rèn)訪(fǎng)問(wèn)級(jí)別一樣,可以直接訪(fǎng)問(wèn)ProtectedClass的printX()方法,上述代碼可以編譯通過(guò)。

在不同的包中調(diào)用ProtectedClass類(lèi)代碼如下:

// 默認(rèn)包中HelloWorld.java文件

import com.a51work6.ProtectedClass;

public class HelloWorld {

public static void main(String[] args) {

ProtectedClass p;

p = new ProtectedClass();

// 編譯錯(cuò)誤,不同包中不能直接訪(fǎng)問(wèn)保護(hù)方法printX()

p.printX();

}

}

該HelloWorld.java文件與ProtectedClass類(lèi)不在同一個(gè)包中,不同包中不能直接訪(fǎng)問(wèn)保護(hù)方法printX(),所以p.printX()方法無(wú)法編譯通過(guò)。

在不同的包中繼承ProtectedClass類(lèi)代碼如下:

// 默認(rèn)包中SubClass.java文件

import com.a51work6.ProtectedClass;

public class SubClass extends ProtectedClass {

void display() {

//printX()方法是從父類(lèi)繼承過(guò)來(lái)

printX(); ①

//x實(shí)例變量是從父類(lèi)繼承過(guò)來(lái)

System.out.println(x); ②

}

}

不同包中SubClass從ProtectedClass類(lèi)繼承了printX()方法和x實(shí)例變量。代碼第①行是調(diào)用從父類(lèi)繼承下來(lái)的方法,代碼第②行是調(diào)用從父類(lèi)繼承下來(lái)的實(shí)例變量。

提示 訪(fǎng)問(wèn)成員有兩種方式:一種是調(diào)用,即通過(guò)類(lèi)或?qū)ο笳{(diào)用它的成員,如p.printX()語(yǔ)句;另一種是繼承,即子類(lèi)繼承父類(lèi)的成員變量和方法。

  • 公有訪(fǎng)問(wèn)級(jí)別任何情況下兩種方式都可以;
  • 默認(rèn)訪(fǎng)問(wèn)級(jí)別在同一包中兩種訪(fǎng)問(wèn)方式都可以,不能在包之外訪(fǎng)問(wèn);
  • 保護(hù)訪(fǎng)問(wèn)級(jí)別在同一包中與默認(rèn)訪(fǎng)問(wèn)級(jí)別一樣,兩種訪(fǎng)問(wèn)方式都可以。但是在不同包之外只能繼承訪(fǎng)問(wèn);
  • 私有訪(fǎng)問(wèn)級(jí)別只能在本類(lèi)中通過(guò)調(diào)用方法訪(fǎng)問(wèn),不能繼承訪(fǎng)問(wèn)。

提示 訪(fǎng)問(wèn)類(lèi)成員時(shí),在能滿(mǎn)足使用的前提下,應(yīng)盡量限制類(lèi)中成員的可見(jiàn)性,訪(fǎng)問(wèn)級(jí)別順序是:私有級(jí)別→默認(rèn)級(jí)別→保護(hù)級(jí)別→公有級(jí)別。

靜態(tài)變量和靜態(tài)方法

有一個(gè)Account(銀行賬戶(hù))類(lèi),假設(shè)它有三個(gè)成員變量:amount(賬戶(hù)金額)、interestRate(利率)和owner(賬戶(hù)名)。在這三個(gè)成員變量中,amount和owner會(huì)因人而異,對(duì)于不同的賬戶(hù)這些內(nèi)容是不同的,而所有賬戶(hù)的interestRate都是相同的。

amount和owner成員變量與賬戶(hù)個(gè)體有關(guān),稱(chēng)為“實(shí)例變量”,interestRate成員變量與個(gè)體無(wú)關(guān),或者說(shuō)是所有賬戶(hù)個(gè)體共享的,這種變量稱(chēng)為“靜態(tài)變量”或“類(lèi)變量”。

靜態(tài)變量和靜態(tài)方法示例代碼如下:

// Account.java文件

package com.a51work6;

public class Account {

// 實(shí)例變量賬戶(hù)金額

double amount = 0.0; ①

// 實(shí)例變量賬戶(hù)名

String owner; ②

// 靜態(tài)變量利率

static double interestRate = 0.0668; ③

// 靜態(tài)方法

public static double interestBy(double amt) { ④

//靜態(tài)方法可以訪(fǎng)問(wèn)靜態(tài)變量和其他靜態(tài)方法

return interestRate * amt; ⑤

}

// 實(shí)例方法

public String messageWith(double amt) { ⑥

//實(shí)例方法可以訪(fǎng)問(wèn)實(shí)例變量、實(shí)例方法、靜態(tài)變量和靜態(tài)方法

double interest = Account.interestBy(amt); ⑦

StringBuilder sb = new StringBuilder();

// 拼接字符串

sb.append(owner).append("的利息是").append(interest);

// 返回字符串

return sb.toString();

}

}

static修飾的成員變量是靜態(tài)變量,見(jiàn)代碼第③行。staitc修飾的方法是靜態(tài)方法,見(jiàn)代碼第④行。相反,沒(méi)有static修飾的成員變量是實(shí)例變量,見(jiàn)代碼第①行和第②行;沒(méi)有staitc修飾的方法是實(shí)例方法,見(jiàn)代碼第⑥行。

注意 靜態(tài)方法可以訪(fǎng)問(wèn)靜態(tài)變量和其他靜態(tài)方法,例如訪(fǎng)問(wèn)代碼第⑤行中的interestRate靜態(tài)變量。實(shí)例方法可以訪(fǎng)問(wèn)實(shí)例變量、其他實(shí)例方法、靜態(tài)變量和靜態(tài)方法,例如訪(fǎng)問(wèn)代碼第⑦行interestBy靜態(tài)方法。

調(diào)用Account代碼如下:

// HelloWorld.java文件

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

// 訪(fǎng)問(wèn)靜態(tài)變量

System.out.println(Account.interestRate); ①

// 訪(fǎng)問(wèn)靜態(tài)方法

System.out.println(Account.interestBy(1000)); ②

Account myAccount = new Account();

// 訪(fǎng)問(wèn)實(shí)例變量

myAccount.amount = 1000000; ③

myAccount.owner = "Tony"; ④

// 訪(fǎng)問(wèn)實(shí)例方法

System.out.println(myAccount.messageWith(1000)); ⑤

// 通過(guò)實(shí)例訪(fǎng)問(wèn)靜態(tài)變量

System.out.println(myAccount.interestRate); ⑥

}

}

調(diào)用靜態(tài)變量或靜態(tài)方法時(shí),可以通過(guò)類(lèi)名或?qū)嵗{(diào)用,代碼第①行Account.interestRate通過(guò)類(lèi)名調(diào)用靜態(tài)變量,代碼第②行Account.interestBy(1000)是通過(guò)類(lèi)名調(diào)用靜態(tài)方法。代碼第⑥行是通過(guò)實(shí)例調(diào)用靜態(tài)變量。

靜態(tài)代碼塊

前面介紹的靜態(tài)變量interestRate,可以在聲明同時(shí)初始化,如下代碼所示。

public class Account {

// 靜態(tài)變量利率

static double interestRate = 0.0668;

...

}

如果初始化靜態(tài)變量不是簡(jiǎn)單常量,需要進(jìn)行計(jì)算才能初始化,可以使用靜態(tài)(static)代碼塊,靜態(tài)代碼塊在類(lèi)第一次加載時(shí)執(zhí)行,并只執(zhí)行一次。示例代碼如下:

// Account.java文件

package com.a51work6;

public class Account {

// 實(shí)例變量賬戶(hù)金額

double amount = 0.0;

// 實(shí)例變量賬戶(hù)名

String owner;

// 靜態(tài)變量利率

static double interestRate;

// 靜態(tài)方法

public static double interestBy(double amt) {

// 靜態(tài)方法可以訪(fǎng)問(wèn)靜態(tài)變量和其他靜態(tài)方法

return interestRate * amt;

}

// 靜態(tài)代碼塊

static { ①

System.out.println("靜態(tài)代碼塊被調(diào)用...");

// 初始化靜態(tài)變量

interestRate = 0.0668; ②

}

}

上述代碼第①行是靜態(tài)代碼塊,在靜態(tài)代碼塊中可以初始化靜態(tài)變量,見(jiàn)代碼第②行,也可以調(diào)用靜態(tài)方法。

調(diào)用Account代碼如下:

// HelloWorld.java文件

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

Account myAccount = new Account(); ①

// 訪(fǎng)問(wèn)靜態(tài)變量

System.out.println(Account.interestRate); ②

// 訪(fǎng)問(wèn)靜態(tài)方法

System.out.println(Account.interestBy(1000));

}

}

Account靜態(tài)代碼塊是在第一次加載Account類(lèi)時(shí)調(diào)用。上述代碼第①行是第一次使用Account類(lèi),此時(shí)會(huì)調(diào)用靜態(tài)代碼塊。

本章小結(jié)

本章主要介紹了面向?qū)ο蠡A(chǔ)知識(shí)。首先介紹了面向?qū)ο笠恍┗靖拍?,面向?qū)ο笕齻€(gè)基本特性。然后介紹了類(lèi)、包、方法重載和訪(fǎng)問(wèn)控制。最后介紹了靜態(tài)變量、靜態(tài)方法和靜態(tài)代碼塊。

配套視頻

http://www.zhijieketang.com/classroom/6/courses

配套源代碼

http://www.zhijieketang.com/group/5

與本書(shū)免費(fèi)版對(duì)應(yīng)的還有一個(gè)收費(fèi)版本:

  1. 進(jìn)入百度閱讀電子書(shū)

  2. 進(jìn)入圖靈社區(qū)電子書(shū)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 《Java從小白到大?!芳堎|(zhì)版已經(jīng)上架了?。?! 面向?qū)ο笫荍ava最重要的特性。Java是徹底的、純粹的面向?qū)ο笳Z(yǔ)...
    tony關(guān)東升閱讀 471評(píng)論 0 1
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,626評(píng)論 18 399
  • 一、Java 簡(jiǎn)介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)...
    子非魚(yú)_t_閱讀 4,538評(píng)論 1 44
  • 本來(lái)我以為畫(huà)面會(huì)是異常溫馨的,兩個(gè)孩子在一起玩耍,我們?cè)谝慌阅⒁曋?,然后像小時(shí)候一樣邊吃東西邊躺在沙發(fā)上漫天聊...
    小丸子的明天閱讀 1,036評(píng)論 15 18
  • 剛剛過(guò)去的一周,是非常充實(shí)而忙碌的一周,工作方面上班的第一天2號(hào)去進(jìn)行技術(shù)交流,第二天3號(hào)培訓(xùn)開(kāi)課,第三...
    76ee95b745bb閱讀 132評(píng)論 0 0

友情鏈接更多精彩內(nèi)容