標籤:特殊許可權 問題 開始 難度 alt 上進 重新編譯 調用 pack
一.
不同的包有很多,不同包之間的類該如何訪問呢?之前沒有包的時候都是預設包,當前這個目錄就是預設包,它們都在同一個包裡進行互相訪問(不同類之間的訪問,調用)。現在看不同包裡類與類之間的訪問又是怎樣的?
上一節的自動產生的包中,包名的確定是根據程式中自己書寫的名字,來確定的。比如這樣的,寫成package mypack;那麼自動形成的包名就是mypackage,而且在運行時會交代形成包的位置(錯誤,是編譯時間形成)。
現在開始對實際的不同包裡的類之間的互動,進行講述。
(原始碼的位置在哪兒?不同的包裡)
現在有兩個包,mypackage和packagea包,mypackage中調用了packagea包中的類。
那麼先編譯誰呢?先編譯DemoA,沒有DemoA,調用它的會失敗。
以前談論的時候,好像是直接編譯PackageDemo類就可以,系統會去自動尋找要訪問的類。
之前講述的是真的,為什麼現在又改變了呢?其實沒改,以前是寫在同一個包裡,所以它會在當前這個包裡去找訪問的類,沒有這個類,就找所在的.java檔案(找到後,編譯一下,再繼續執行程式)。這個規律還是這個事兒。的程式在執行的時候,要找DemoA類檔案,如果DemoA類檔案在目前的目錄下沒有,那麼就要先找DemoA.java檔案,可是這個以前確實有一點不一樣的是,這個DemoA已經有所屬了。
所以,你要用的類實際上是packagea.DemoA.class檔案,如果沒有這個類檔案的話,它會找packagea目錄下有沒有DemoA.java檔案。它根據你這個類名來尋找源檔案名稱,(看來尋找時的原理確實沒有變化,只是要根據位置做一個變化)
(我稍微有那麼一點明白了,添加了包語句的程式,使用方法和以前稍有不同。現在被調用的類檔案,名稱必須是包名.類名,如果類檔案僅是類名,那麼就無法操作。如果沒有對應的類檔案,調用者還會到對應的包檔案下,去尋找相應類名的類檔案。這個類檔案需要包名.類名的格式嗎?不需要,在來源程式中需要,類檔案的擺放位置需要按照這個規格來)
現在通過示範操作,來具體展示整個流程。
實操中,直接採用javac DemoA,得到的是目前的目錄下DemoA.class檔案,但是PackageDemo類檔案運行時無法使用它,因為名稱不對。這裡的DemoA類檔案使用的是當前包.DemoA.class的名稱,這樣對不上了,運行自然失敗。(但是編譯還是可以的,形成目前的目錄下的DemoA.class檔案)
現在要將其修改為能用的形式。其實之前說過怎麼將其變為可用的形式,有兩種:手動和自動。現在以自動的形式來操作,這裡要還注意一點,javac –d . DemoA.java時,原始碼的名稱DemoA.java和程式裡的類名存在微弱的關係。
經過自動編譯後(手動操作也是這樣的結果),在目前的目錄下形成一個packa的包,同時包裡存在一個DemoA.class的類檔案。
現在聯想最早之前講述過的例子,目前的目錄下有兩個原始碼,存在一個調用與被調用的問題。實際情況中,可以將二者都編譯出來,最終運行調用類檔案即可。也可以只編譯運行調用來源程式,它會在運行時,自動搜尋被調用的類檔案,如果沒有就找相應名稱的源檔案,將其編譯,再調用的它的類檔案。在包機制下,這個原理也同樣是適用的。
在包的機制下,首先要注意的大前提是,在編譯運行中源檔案名稱和類檔案名稱都有了擴充,雖然實際看上去名稱沒有變化,但實際上進行了擴充。
包出現後,類檔案(也就是位元組碼檔案)可以和java源檔案分離。咱們只需要將類檔案給別人用就行,不需要將源檔案給別人用。現在提高使用難度,將編譯的類檔案完全提出去。
這就實現了源檔案和類檔案分離。現在接著調用程式的編譯,運行。
編譯出現了兩個錯誤,找不到DemoA。
以前為什麼不寫,以前是在一個包裡,現在分在不同的包裡了。(在來源程式書寫時,就要明確調用類的所屬。)
也就是要修改來源程式
這才是正確的類名,現在繼續編譯執行,又是報錯
這次顯示包不存在,
在目前的目錄下沒找到packa包
其實這個倒不難理解,編譯是在E:\java0331\day12下進行的.java源檔案編譯,packageDemo.java源檔案在編譯時間,需要調用packa.DemoA檔案,但是在當前檔案下沒有packa包。這個包在c盤下,應該設定classpath,告訴虛擬機器在什麼路徑下(對以前的set classpath知識有所遺忘。我的理解是這樣的,在目前的目錄下,編譯packageDemo.java源檔案時,用到了packa.DemoA類,也就是說在目前的目錄下要尋找packa包中的DemoA類檔案,如果沒有的話,找到對應的DemoA.java也是可以的,可惜的是都不存在這樣的包。這裡突然產生一個疑問,需要的一定是DemoA的類檔案,而不是.java源檔案嗎?無論哪個檔案都需要在程式中描寫的那樣,在對應的包下面。由於對應的包在c盤中,現在我們需要將c盤加入進來,也就是採用set classpath的方法。我個人覺著,set classpath是添加了一條搜尋路徑。那麼類檔案的產生位置和set classpath有關嗎?)。
記住,配置包的時候,你直接把包所在的目錄配置到classpath中,不要配置類檔案的,因為包和類是一個整體,(指向包所在的所屬)
繼續編譯,還是出錯,
報告中說,不是公用的,就是在說許可權問題。
包裡面定義一個類的話,如果這個類要在包裡面被訪問,必須要給它足夠大的許可權,一般許可權訪問不到。包裡面的類,如果沒有加public,就是在包裡面被封裝了,就是隱藏,不是說加了private才是隱藏。
注意一點的就是,加了public,源檔案名稱和類名就要保持一致了。
在修改完這個之後,再次進行編譯運行。
就是說DemoA類改為公有了,但是裡面的show方法還沒公有,還需要修改。預設許可權不行,它也屬於封裝。
這時需要重新編譯DemoA類,因為它進行過修改了。
這時候沒有任何問題了,而且packageDemo類檔案也存放在c盤myclass檔案下。
現在才是真正瞭解許可權的用法,包與包之間才體現出來,一個包裡面無法體現出許可權的用法。
二.
不同包裡的類之間的繼承問題。
建立一個packb的包,以及裡面的類,
Packa包中的類繼承了packb包中的類,這就是不同包裡類之間的繼承。
上面中的寫法是錯誤的,DemoB是不存在的,都要有首碼的,現在和之前不一樣了。
既然是繼承,那麼我們可以直接運行method()方法,因為繼承了DemoB的一切。
編譯的時候,源檔案寫成Demoa也是可以編譯的,圖中的packa包就是javac –d c:\myclass Demoa.java產生的。下面一句javac –d c:\myclass DemoA.java只是個形式。
這幾幅圖,重要的是兩點,編譯時間在固定的地方形成檔案夾,運行時加了首碼名。在包的機制下,大前提就是原始碼中的書寫很重要。
現在考慮另外一個問題,上面的是子類調用父類的方法是直接存取的,
這時又提出一個問題,a繼承b調用method方法,和b自己調用method方法,得出的結果是一樣的,都是DemoB method run,現在就是問兩者形成的東西都是一樣的,為什麼還要繼承?
上面說錯了,說的是,packageDemo類不用繼承Demob類,就可以直接建立Demob類對象,並直接調用其方法。就是通過建立外部類的對象,實現了訪問外部類的方法。而DemoA類是通過繼承,才獲得了Demob的方法。現在問題就是繼承還有什麼,沒有體現出差異來。
是不是子類,方法都可以拿過來用。那麼,這繼承的存在有些多餘。現在進行一個許可權的修改,不同包之間不允許你來訪問,但是如果是繼承關係,就同意訪問。這種就是特殊許可權,給不同包的子類使用的。Public的存在,誰都可以使用,有沒有繼承都無所謂。
加了protected的許可權,只有不同包中的子類能夠使用。你直接在不同包裡建立其對象的話,無法擷取其方法。
再次啟動並執行結果如下,和之前的不太一樣。
這protected是大家學習到的第四種許可權,用的不多,但是必須要知道。只有繼承了,這個功能才能去使用。換句話說,只有所屬於這個體系,才能讓你用。這個其實,也叫做封裝。我不讓跟我沒關係的類,來訪問我這個功能,這專門為我的子類所提供的。
包與包之間能用的許可權只有兩個,一個是public,另一個是protected,而protected只能給不同包中的子類使用。
JAVA-初步認識-第十二章-物件導向(包與包之間的訪問)