第八章 package
description
Transcript of 第八章 package
Java2 程式實務1
第八章 package第八章 package
• 程式碼及函式庫管理– 傳統的程式語言, C 及 PASCAL ,抑或是較新
的物件導向程式語言如 C++ 等:• 程式語言本身並沒有任何的機制去管理程式碼及函式
庫等瑣碎繁雜的檔案。– Java :
• 以類別為主的程式編譯方式,• 以 package 來管理組織類別,使得系統發展能夠以一
種有效率的方式進行。
Java2 程式實務2
第八章 package第八章 package
• 程式單元( .class 檔案 )– 一般的程式語言
• 以檔案為單位來編譯程式,很自然的,原始程式在編譯後就產生以檔案名稱為主的目標檔案 (object file) 。
• 無論在原始檔案中包含了多少個函數或是類別的定義,程式設計師所面對的就是一個包含多個函數或類別的目標檔案。
– 遭遇的困難:• 因此,如果想在函數或類別撰寫時就作好分門別類的
管理,幾乎是不可能的事。
Java2 程式實務3
第八章 package第八章 package
• Java– 所有的類別在編譯後都會產生一個或一個以上的,
以程式中類別的名稱為主,且附加名為 class 的檔案。
– 所有的 Java 程式都是以類別為主的,一個 .class 檔案 ( 其中只包含一個類別的定義 ) ,就稱為一個程式單元。
Java2 程式實務4
第八章 package第八章 package
• 一個名為 A.java 的檔案:class A { …}
class B { …}
class C { …}
在編譯後,這個 A.java 檔案就會產生 3 個 class 檔案,分別為 A.class , B.class 及 C.class 。
Java2 程式實務5
第八章 package第八章 package
• Java 程式寫作規定:– 在 Java 的程式寫作規範上(詳見本書附錄)有
特別規定,那就是在一個 Java 程式中衹可以定義一個 public 類別,或是一個 public 類別加上其他的非 public 類別所組合而成。當然,檔案名稱也必須與這個 public 類別的名稱一致,否則就會產生編譯錯誤。
– (注意,在 Win32 系統中,檔案名稱的大小寫與程式中所定義類別的名稱是相同的)
Java2 程式實務6
第八章 package第八章 package
• 因此,在以 Java 發展軟體時,原始碼的管理變得較以往簡單。– 一個檔案中祇有定義一個 public 類別,我們可
以很輕易的由檔案名稱就知道這些 public 類別的原始程式所在位置。
Java2 程式實務7
第八章 package - 什麼是 package ( 包裹 )第八章 package - 什麼是 package ( 包裹 )
• 設計概念– 將類別於系統發展階段時就將其做分類管理,以
便於系統在日後的發展及使用上能夠更為便利。
Java2 程式實務8
第八章 package第八章 package
• 如何定義 package ?– package 的定義是十分簡單的,那就是在程式中非註解的第一行程式用以下的方式定義 package:
• package package 名稱 ;
– 例:• package myFirstPackage;
• package basicPackage;
Java2 程式實務9
第八章 package第八章 package
• package 名稱可以是一個簡單名稱也可以是一串以 ‘ .’ 連結的字串所形成的名稱:– package graphics;– package java.io;– package java.awt.swing.plaf.basic;– package org.omg.CORBA;– package java.awt.dnd.peer;
Java2 程式實務10
第八章 package - 在專案中定義 package第八章 package - 在專案中定義 package
• 在程式中定義了 package 後,就是將程式中所定義的類別歸屬於所定義的 package 中。
• 如果在程式中並沒有定義任何 package 的話,這些未定義任何 package 的類別都自動歸屬於一個沒有名字的 package 。
• 這個沒有名字的 package , Java 稱它為 default package ( 預設包裹 ) 。
Java2 程式實務11
第八章 package第八章 package
• 在 Java 中可以將不同性質、用途的類別分別歸屬到不同的 package 中。
// 檔案名稱: Draw.javapackage graphics; // 定義類別 Draw 屬於 package graphics 。
class Draw { …} // 檔案結束
// 檔案名稱: Paint.javapackage graphics; // 定義 Paint 類別屬於 package graphics
class Paint { …} // 檔案結束
Java2 程式實務12
第八章 package第八章 package
• 注意:一個 Java 檔案衹能定義有一個 package 敘述,也就是說,在一個 Java 檔案中的所有類別,只能屬於一個 package 。
• 如果在程式中完全沒有定義任何 package , Java 會將所有沒有定義 package 的類別歸屬於預設 package 之下。– 也就是說,這些類別都是定義於同一個預設的
package scope ( 生存範圍 ) 之中,而在同一個 package 的類別相互之間則可以互相叫用。
Java2 程式實務13
第八章 package第八章 package
• 建議在發展程式時,先將程式設定為某一個 package ,那麼,程式中的資源就能夠獲得 package 的保護,而不會被其他程式意外的破壞。
Java2 程式實務14
第八章 package第八章 package
java
util lang io
•在 java 這個專案之下,可以再分為 util , lang 及 io 等子專案。•為了要表示專案間相互的從屬關係,我們就可以將其表示為 java.util , java.lang 及 java.io 等。
Java2 程式實務15
第八章 package第八章 package
• 例如:– 在 java.lang 之中定義的 String 類別,其完整的
名稱就是 java.lang.String 。– 定義在 java.util 之中的例外
EmptyStackException 的完整名稱就成為 java.util.EmptyStackException ,
– 定義在 java.io 中的例外 NotActiveException 的完整名稱就成為 java.io.NotActiveException 。
Java2 程式實務16
第八章 package第八章 package
• 以程式為例:package java.io;
class NotActiveException extends Exception { ...}
Java2 程式實務17
第八章 package - 如何編譯及執行 package 中的程式第八章 package - 如何編譯及執行 package 中的程式
• 在 jdk 中編譯已定義 package 的 java 檔案:– 需要在 javac 後加上 ‘ -d’ 這個選項。
• 這個選項的意義是:將要產生的 package 及編譯後所產生的 class 檔案放置在 ‘ -d’ 後所指定的路徑中,在編譯後, javac 才會幫我們依照 package 的定義,在目錄中去產生 .class 檔案。
– 程式中所定義的 package ,其實就是檔案系統中的相對路徑。
Java2 程式實務18
第八章 package第八章 package
• 例如:– 就之前的 graphics package 範例:
• javac –d . Draw.java
• javac –d . Paint.java
– 分別在 java 檔案所在的現行工作目錄下編譯產生 class 檔案。
• 編譯後的 Draw.class 及 Paint.class 將會被存放於:– .\graphics\Draw.class
– .\graphics\Paint.class
Java2 程式實務19
第八章 package第八章 package
• 執行 package 中的程式:– 在編譯完後直接執行。
• 特別注意的是:千萬不要進入 package 的目錄中去執行 .class 檔案,祇要在 package 所在的根目錄,用以上的例子來說,就只需留在原工作目錄執行即可。
– 如: java graphics.Draw
– 使用 javac 的 ‘ -classpath’ 選項。• 如: java –classpath .;c:\MyJava\MyClass\ graphics.Draw
Java2 程式實務20
第八章 package第八章 package
– 定義 jdk 所使用的環境變數 classpath 。• 將路徑直接定義在 classpath 的環境變數中。
– set classpath=c:\MyJava\MyClass
• 可以在任何路徑下執行下面這個命令:– java graphics.Draw
Java2 程式實務21
第八章 package - 如何產生 jar 檔案第八章 package - 如何產生 jar 檔案
• Java 中的 jar ,是 Java ARchive (Java 文件檔 ) 的簡稱。
• jar 是類別所成的集合。
Java2 程式實務22
第八章 package第八章 package
c 產生新的文件檔案輸出於 stdout
t 將 stdout 的輸出內容列表顯示
x files 從 stdout 中擷取所有檔案,或其中某些指定於 files 中的檔案。如果沒有指定,則擷取所有檔案。
f file 指定使用的檔案名稱。如與 c 配合使用,則產生新的以 file 為名的 jar 檔案。如與 t 配合使用,則將以 file 為名的檔案內容列表輸出。如與 x 配合使用,則將擷取以 file 為名的 jar 檔案。
v 將 jar 的運作過程顯示出來。
u 更新 jar 的內容。
Java2 程式實務23
第八章 package第八章 package
• 以 8-3 中的程式為例,在工作目錄中使用以下命令:– jar cvf myPackage.jar graphics
• jar 將會自動將子目錄 graphics 中的所有子目錄及檔案加入新檔 myPackage.jar 中。
• 如果有新版本的 graphics.Draw.class 檔,也可以以下列命令加以更新:– jar uvf myPackage.jar graphics\Draw.class
Java2 程式實務24
第八章 package - 使用其他的 package 及類別來發展程式第八章 package - 使用其他的 package 及類別來發展程式
• jdk1.3 中所有的系統 package 是不用在 classpath 中設定,它們能夠被系統自動確認其所在位置 ( 系統安裝時的預設路徑)。
• 其他外來的 package , jdk 則需要一種方式來搜尋這些外來的 jar 檔案。那就是在前面所提,經由 classpath 環境變數去設定。
Java2 程式實務25
第八章 package第八章 package
• 在程式中使用 package 的方式,有二種方式
– 使用 import 敘述。• 在 Java 程式的開頭部分,我們常常可以看到一行或
數行程式,如:– import java.io.*;
– import java.util.*;
– import java.awt.Font;
• 將其他的 package 引入目前 package 的生存範圍中,使得程式設計師能夠在程式中直接使用 package 中的類別名稱。
Java2 程式實務26
第八章 package第八章 package
import java.io.*;
class Main { public static void main(String[] args) { BufferedReader in = new BufferedReader(…); // BufferReader 是定義在 java.io 中的類別。 …; }}
Java2 程式實務27
第八章 package第八章 package
• import 敘述中的 ‘ *’ 字元(萬用字元)。– java.io 這個 package 中所有的 類別。– 不能寫
• import java.*;
• 來代表所有以 java 為首的 package 名稱。– 這個星號衹能代表一般的簡單名稱,且必須出現
在 import 敘述的最後,不能在名稱的中間。• import java.*.String; // 錯誤的用法!
Java2 程式實務28
第八章 package第八章 package
• 直接用類別完整的名稱來直接引用。– 如果沒有使用 import 敘述來引入 package ,我
們也可以直接用類別完整的名稱來直接引用。
class Main { public static void main(String[] args) { java.io.BufferReader in = new java.io.BufferedReader(...); ...; }}
Java2 程式實務29
第八章 package第八章 package
• jdk 中的 java.lang 是唯一不用 import 敘述,而能夠被系統自動 import 的 package 。
Java2 程式實務30
第八章 package - 類別在 package 中的存取限制第八章 package - 類別在 package 中的存取限制
• 類別可以經由設定存取限制來限定其是否可以被其他 package 中的類別所使用。
• 在 package 中的類別只能夠被設定為 public 。
• 當類別被設定為 public 之後,就可以被其他 package 所使用。沒有被設定 public 的類別則不可以被其他 package 的類別所使用。
• 在程式中使用了其他 package 中不是設定為 public 的類別,則會導致編譯錯誤。
Java2 程式實務31
第八章 package第八章 package
// 檔案: M.javapackage myPackage;
class C { public C() { System.out.println("myPackage.C()"); }}
public class M { public M() { System.out.println("myPackage.M()"); }}
import myPackage.*;
class G { public static void main(String[] args) { C c = new C(); // 編譯錯誤! // 類別 C 不可被其他 package 的類別使用! M m = new M(); }}
Java2 程式實務32
第八章 package - 預設存取第八章 package - 預設存取
• 預設存取,就是指類別中的各種資源 ( 變數及方法 ) 並沒有設計任何的存取限制 (public, private 及 protected) 。
• 這類的資源在同一個 package 中的使用可說是毫無限制,與 public 設定幾無差別。可是在不同的 package 中使用時,這些被設定為預設存取的資源則完全不能被使用。如同是 private 設定一般。
Java2 程式實務33
第八章 package第八章 package
// 檔案: D.javapackage myPackage;
class C { int i;}
public class D { public static void main(String[] args) { C c = new C(); c.i = 10; // OK! // 類別 C 與類別 D 定義在同一個 package 中。 }}
// 檔案: M.javaimport myPackage.*;
public class M { // 類別 D 屬於 default package! public static void main(String[] args) { C c = new C(); c.i; // 編譯錯誤! // 不可使用 myPackage 中的預設存取資源! }}