解析Java編程中對(duì)于包結(jié)構(gòu)的命名和訪問(wèn)
包的命名
包的名字應(yīng)該避免與其他包沖突,所以選擇一個(gè)既有意義又唯一的名字是包設(shè)計(jì)的一個(gè)重要方面。但是全球的程序員都在開發(fā)包,根本就沒(méi)有辦法獲知誰(shuí)采用了什么包名,因此選擇唯一的包名是一個(gè)難題。如果我們確定某個(gè)包只在我們的組織內(nèi)部使用,那么我們就可以讓內(nèi)部仲裁者(internal arbiter)來(lái)確保項(xiàng)目之間不會(huì)發(fā)生名字沖突。
但是對(duì)于整個(gè)世界而言,這種方法是不實(shí)際的。包的標(biāo)識(shí)符都是簡(jiǎn)單的名字,一種比較好的能夠確保包名唯一的方法是使用Internet域名。如果我們所就職的公司的名字為Magic.lnc,該公司的域名為magi c.com,那么屬性包的聲明就應(yīng)該是:
package com.magic.attr; 注意,這里的域名構(gòu)成元素是按常規(guī)域名的倒序排列的。
如果我們采用這種慣用法,那么除了在我們的組織內(nèi)部可能會(huì)產(chǎn)生沖突外,我們所采用的包名就不會(huì)與其他任何人的包名沖突了。如果我們的組織內(nèi)部確實(shí)產(chǎn)生了沖突(可能是大型的企業(yè)),那么我們可以使用更具體的域名來(lái)進(jìn)一步限定。許多大型公司都有內(nèi)部子域名,如east和europe,可以使用這樣的子域名來(lái)進(jìn)一步限定包的名字:
package corn. magic.japan.attr;
使用這種方案可能會(huì)使包的名字變得很長(zhǎng),但是相對(duì)比較安全。使用這種技巧的程序員不會(huì)選擇相同的包名,而不使用這種技巧的程序員也不會(huì)選擇我們所采用的名字。
包的訪問(wèn)
在聲明包中的頂層類和頂層接口的可訪問(wèn)性時(shí),有兩種選擇:包訪問(wèn)權(quán)限(package)和公共訪問(wèn)權(quán)限(public)。用public修飾的類或接口可以被包外的代碼所訪問(wèn),而沒(méi)有用public修飾的類型則具有包作用域:它們可以被同一個(gè)包中的其他代碼所訪問(wèn);但對(duì)于包外的代碼,甚至是子包中的代碼,它們都是隱藏的。我們?cè)诼暶黝愋蜁r(shí),應(yīng)該只把其他程序員需要使用的那些類型聲明為public的,而隱藏那些屬于包的實(shí)現(xiàn)細(xì)節(jié)的類型。這種技術(shù)給我們提供了極大的靈活性,由于程序員并不依賴于這些他們所不能訪問(wèn)的實(shí)現(xiàn)細(xì)節(jié)的類型,所以當(dāng)我們想改變實(shí)現(xiàn)細(xì)節(jié)時(shí),可以自由地改變它們。
沒(méi)有被聲明為public,protected或private的類成員可以被包內(nèi)的任何代碼直接訪問(wèn),但對(duì)包外的代碼是隱藏的。換句話說(shuō),默認(rèn)的訪問(wèn)修飾符是“package",但接口的成員例外,它們的默認(rèn)訪問(wèn)修飾符是“public" .
在包內(nèi)沒(méi)有聲明為private的字段或方法可以被該包中的所有其他代碼所訪問(wèn),因此,同一個(gè)包中的類都被認(rèn)為是“友好的”或“可以信任的”。這樣就使得我們可以定義組合了預(yù)定代碼(predefined code)和占位符代碼(placeholder code)的應(yīng)用框架,其中占位符代碼被框架類的子類覆蓋。預(yù)定義代碼可以使用包訪問(wèn)權(quán)限修飾符,這樣包內(nèi)的其他相互協(xié)作的代碼就可以直接訪問(wèn)它們,但對(duì)于包外用戶,這些代碼是不可訪問(wèn)的。然而,這些代碼所在包的子包是不被信任的,反之亦然。例如,在包dit中用包訪問(wèn)權(quán)限修飾符修飾的代碼不能被其子包dit.dat中的代碼所訪問(wèn),反之亦然。
因此,每種類型都定義了三種不同的契約:
- .publi。契約:定義了類型的主要功能。
- .protected契約:定義了子類可獲得的用于特化目的的功能。
- .package契約:定義了包內(nèi)其他代碼可獲得的用來(lái)實(shí)現(xiàn)包內(nèi)類型之間協(xié)作的功能。所有這些契約都需要仔細(xì)考慮和設(shè)計(jì)。
可訪問(wèn)性和及蓋方法
只有在超類中可以訪問(wèn)到的方法才可以在子類中被覆蓋。如果超類中的某個(gè)方法不能被訪問(wèn),那么即使子類中的方法與該方法同名,在子類中也不能覆蓋該方法。當(dāng)某個(gè)方法在運(yùn)行時(shí)被調(diào)用時(shí),系統(tǒng)會(huì)考慮它的可訪問(wèn)性,從而決定運(yùn)行它的哪一個(gè)具體實(shí)現(xiàn)。
下面這個(gè)特意構(gòu)建的例子解釋得更加清楚。假設(shè)我們?cè)赑1包中聲明了一個(gè)Abstract-Base類:
package P1;
{Ab Ab AbAb
public abstract class AbstractBase
private void pri() {print(" stractBase.pri()”):} void pac () {print(" stractBase.pac()”);}
protected void pro() {print(" stractBase.pro()");}
public void pub() {print(" stractBase.pub()”);}
public final void show()
pri();
pac();
pro();
pub();
}
}
在這個(gè)類中,我們定義了4個(gè)方法,每個(gè)方法都具有不同的訪問(wèn)權(quán)限修飾符,且方法體都只是標(biāo)識(shí)其自身。方法show在當(dāng)前對(duì)象上依次調(diào)用了這4個(gè)方法,當(dāng)把該方法應(yīng)用于不同的子類對(duì)象時(shí),就可以說(shuō)明到底調(diào)用了這些方法的哪個(gè)實(shí)現(xiàn)。
現(xiàn)在,我們定義類Concretel,這個(gè)類擴(kuò)展了AbstractBase類,但是位于P2包中:
package P2;
import P1.AbstractBase
public class Concretel extends AbstractBase{
public void pri(){print("Concretel.pri()”);}
public void pac(){print("Concretel.pac()”);}
public void pro(){print("Concretel.pro()”);}
public void pub(){print("Concretel.pub()");}
}
在該類中重新聲明了超類中的4個(gè)方法,并改變了它們的實(shí)現(xiàn),這些實(shí)現(xiàn)在報(bào)告它們屬于Con-cretel類。同時(shí),它們的訪問(wèn)權(quán)限都被改成了public,以便其他代碼訪問(wèn)。執(zhí)行下面的代碼
new Concretel().show():
將產(chǎn)生如下輸出:
AbstractBase.pri() AbstractBase.pac() Concretel.pro() Concretel.pub ()
因?yàn)樗接蟹椒╬ri不能被子類(或其他類)所訪問(wèn),所以show方法總是調(diào)用AbstractBase類中的pri方法的實(shí)現(xiàn)。AbstractBase類中的具有包訪問(wèn)權(quán)限的pac方法不能被Concretel訪問(wèn),因此Concretel類中的pac方法的實(shí)現(xiàn)不能覆蓋AbstractBase類中的定義,故show方法調(diào)用的是AbstractBase.pac方法。pro方法和pub方法在Concretel類中都是可以訪問(wèn)的,同時(shí)也可以被覆蓋,所以show方法中調(diào)用的是Concretel類中的這兩個(gè)方法的實(shí)現(xiàn)。
接卜采我們足義類Concrete2,來(lái)擴(kuò)展類Concretel,然后我們把它和AbstractBase類放到同一個(gè)包P1中':
package P1;
import P2.Concretel
public class Concrete2 extends Concretel{
public void pri(){print("Concrete2.pri()”);}
public void pac(){print("Concrete2.pac ()”);}
public void pro(){print("Concrete2.pro()”);}
public void pub(){print("Concrete2.pub()");}
}
因?yàn)镃oncretel中的方法都具有public訪問(wèn)權(quán)限,所以在Concrete2中都可以訪問(wèn)到,而且Concrete2中的每一個(gè)方法分別對(duì)其相應(yīng)的方法進(jìn)行了覆蓋。此外,因?yàn)镃oncrete2和Ab-stractBase在同一個(gè)包中,所以在Concrete2中也可以訪問(wèn)到方法AbstractBase.pac,并且可以覆蓋方法Concrete2.pac。在Concrete2對(duì)象上調(diào)用show方法,打印結(jié)果如下:
AbstractBase.pri() Concrete2.pac() Concrete2 .pro() Concrete2.pub()
最后,我們定義類Concrete3來(lái)擴(kuò)展類Concrete2,并放在包P3中:
package P3
import P1.Concrete2;
public class Concrete3 extends Concrete2{
public void pri(){print("Concrete3.pri()”);}
public void pac Q{print("Concrete3.pac()”);}
public void pro(){print("Concrete3.pro()”);}
public void pub(){print("Concrete3.pub()”);}
}
在Concrete3對(duì)象上調(diào)用show方法,打印結(jié)果如下:
AbstractBase.pri()
Concrete3.pac ()
Concrete3.pro()
Concrete3.pub()
在這里方法Concrete3.pac看起來(lái)是覆蓋了不可訪問(wèn)的AbstractBase.pac方法,但實(shí)際上是,方法Concrete3.pac覆蓋了方法Concrete2.pac,而方法Concrete2.pac覆蓋了方法AbstractBase.pac,因此方法Concrete3.pac間接地覆蓋了方法AbstractBase.pac。通過(guò)在類Concrete2中重新把pac方法聲明為具有public訪問(wèn)權(quán)限,可以使其能夠被任何子類所訪問(wèn)和覆蓋。'
相關(guān)文章
IDEA實(shí)用好用插件推薦及使用方法教程詳解(必看)
這篇文章主要介紹了IDEA實(shí)用好用插件推薦及使用方法教程,本文通過(guò)實(shí)例截圖相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Spring?Security認(rèn)證器實(shí)現(xiàn)過(guò)程詳解
一些權(quán)限框架一般都包含認(rèn)證器和決策器,前者處理登陸驗(yàn)證,后者處理訪問(wèn)資源的控制,這篇文章主要介紹了Spring?Security認(rèn)證器實(shí)現(xiàn)過(guò)程,需要的朋友可以參考下2022-06-06
SpringBoot項(xiàng)目中遇到的BUG問(wèn)題及解決方法
這篇文章主要介紹了SpringBoot項(xiàng)目中遇到的BUG問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Java設(shè)計(jì)模式之Adapter適配器模式
這篇文章主要為大家詳細(xì)介紹了Java設(shè)計(jì)模式之Adapter適配器模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
Spring MVC實(shí)現(xiàn)文件上傳及優(yōu)化案例解析
本文介紹如何在SpringMVC框架中實(shí)現(xiàn)文件上傳和異步登錄功能,通過(guò)添加必要的依賴和配置,創(chuàng)建文件上傳頁(yè)面和控制器,實(shí)現(xiàn)文件上傳到指定文件夾,同時(shí),展示了如何使用AJAX實(shí)現(xiàn)局部刷新的異步登錄,優(yōu)化用戶體驗(yàn),詳細(xì)步驟包括配置springmvc.xml、編寫前端頁(yè)面和控制器等2024-10-10
使用SpringBoot_jar方式啟動(dòng)并配置日志文件
這篇文章主要介紹了使用SpringBoot_jar方式啟動(dòng)并配置日志文件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java程序員必須知道的5個(gè)JVM命令行標(biāo)志
這篇文章主要介紹了每個(gè)Java程序員必須知道的5個(gè)JVM命令行標(biāo)志,需要的朋友可以參考下2015-03-03
本地啟動(dòng)RocketMQ未映射主機(jī)名產(chǎn)生的超時(shí)問(wèn)題最新解決方案
這篇文章主要介紹了本地啟動(dòng)RocketMQ未映射主機(jī)名產(chǎn)生的超時(shí)問(wèn)題,本文給大家分享最新解決方案,感興趣的朋友跟隨小編一起看看吧2024-02-02

