ncyu_phyedu 板


LINE

封裝的意義 物件導向程式設計的原則之一, 是讓實作和界面分開, 以便讓同一界面但不同的實作的物 件能以一致的面貌讓外界存取, 為了達到此目標, java允許設計人員規範類別成員以及類 別本身的存取限制。 類別成員的存取 所謂封裝(Encapsulation),是指class A的設計者可以指定其他的class能否存取A的某個 member。Java定義了四種存取範圍: private:只有A自己才可以存取, 使用keyword private package:只有和A同一個package的class才可以存取, 沒有相對應的keyword protected:只有同一個package或是A的子類別才可以存取, 使用keyword protected public:所有的class都可以存取, 使用keyword public public class EncapsulationExample { private int privateVariable; int packageVariable; protected int protectedVariable; public int publicVariable; private int privateObjectMethod() {} int packageObjectMethod() {} protected int protectedObjectMethod(); public int publicObjectMethod(); static private int privateClassMethod() {} static int packageClassMethod() {} static protected int protectedClassMethod(); static public int publicClassMethod(); } 如果member的前面沒有private,protected,public其中一個修飾字,則該member的存取範 圍就是package。從以上的敘述,讀者可以推知這四種存取範圍的大小是public > protected > package > private。 Package的定義 所謂package,可以想成是在設計或實作上相關的一群class。要宣告某class屬於某 package,其語法為 package myPackage; public class MyClass { } 如果沒有宣告package的話,如下面這兩個class,就會被歸類為「匿名」的package: // in file ClassA.java public class ClassA { public static void main(String[] argv) { ClassB x = new ClassB(); } } // in file ClassB.java public class ClassB { } 為了讓JVM在執行期間能夠找到所需要的class,同一個package的class會放在同一個目錄 下。不過只知道目錄的名稱還不夠,還需要指定該目錄在檔案系統內的路徑。classpath這 個環境變數是由多個以分號隔開的路徑所組成,JVM透過classpath配合package的名稱就可 以找到所需要的class。如果我們只用到Java標準的程式庫,則不需要指定classpath。指 定classpath環境變數時,要特別注意的是,不要忘了把.(代表目前的工作目錄)放到最前面 ,否則就找不到「匿名」package裡的class(別忘了絕大部分簡單的範例都沒有宣告 package,所以都是匿名的)。 classpath=.;n:\計網中心系統組\project; classpath裡除了路徑外,也可以指定zip或jar(java archive format)格式的檔案。zip和 jar可以把目錄及其子目錄內的檔案都壓縮起來,因此可以透過這類檔案抓到所需的class 檔。 classpath=.;c:\mylib.zip;c:\otherlib.jar;n:\計網中心系統組\project; package的宣告可以用.號構成複雜的package tree。 package mylib.package1 public class A {} package mylib.package2 public class B {} 屬於mylib.package1的class會放在mylib目錄下的package1目錄內。Java所提供的標準應 用程式介面(Application Programming Interface, API)就是一個複雜的package tree。 同一個.java檔裡面, 可以定義好幾個class, 但最多只能有一個宣告為public class。此 限制是因為java希望每一個編譯的單元(.java檔)都有唯一的界面宣告。那麼public class和class的區別何在? non public class只能給同一個package內的其他class引用, public class則可以給任何class引用。 Package的引用 假如Class A用到package myPackage裡的Class B, 為了檢查A使用到B的部分是否符合B的 原始定義, 諸如方法存不存在, 參數正不正確等問題, Compiler必須引入class B的定義 , 以便進行編譯時期的檢查。引入的語法為 import myPackage.B; 這裡要強調的是, import指令告知Compiler在Compiler time所要檢查的類別定義在哪裡 。但有時候我們編譯的環境和執行的環境可能不同, 例如編譯時用JDK 1.4, 執行時卻用 JDK 1.2, 若程式使用到JDK 1.4才有的API, 那麼會在執行期間產生錯誤。 有時候我們會引用相當多個同屬某package的類別, 如果要一個一個import, 會很煩人, 因此Java允許我們使用萬用字元*來代表某package裡的所有class: import myPackage.*; public class A { public static void main(String[] argv) { B x = new B(); } } 眼尖的讀者會發現我們並沒有import String的定義啊, 怎麼都沒有問題? 由於寫程式多 多少少都會用到一點系統提供的程式庫, 如果連很簡單的程式都要import一堆class, 也 真煩人。因此Java Compiler會自動幫我們引入java.lang.* public class Hello { public static void main(String[] argv) { System.out.println("Hello World."); } } 就等同 import java.lang.*; public class Hello { public static void main(String[] argv) { System.out.println("Hello World."); } } 由於class是放在類似樹狀結構的package tree裡面, 因此引用的class應該加上完整的 package路徑才是全名, 例如 public class Hello { public static void main(java.lang.String[] argv) { java.lang.System.out.println("Hello World."); } } 只要不會造成混淆, 一般我們都使用省略package路徑的class簡稱。但是如果我們 import P1和P2兩個package, 而這兩個package碰巧都定義了同名的class A, 則用到A的 地方就比需以P1.A和P2.A來區別了。 下面的程式碼哪裡有錯? package p1; public class Access { private static void f1() {} static void f2() {} protected static void f3() {} public static void f4() { Access.f1(); } } package p1; public class Example1 { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } package p2; import p1.*; public class Example2 { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } package p1; public class Example3 extends Access { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } package p2; import p1.*; public class Example4 extends Access { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } Java檔和Class檔的相依性 傳統程式開發的流程是Compile個別Source Code,然後Link所有的Object Code成為執行檔 。對大型的應用程式來說,常見的問題之一是如何確定Link時所需的Object Code是由最新 的Source編譯而來?尤其模組間存在相依性,如模組A可能用到模組B裡的函數,如果B的函數 有修改參數,則A模組也要重新編譯。換句話說單看source code和object code的產生時間 是不行的。最簡單的方法就是在Link前將所有的Source Code重新編譯一次,但這樣做有以 下幾個問題: 重新編譯大型專案全部的程式碼可能會浪費不少時間 要對每個Source File下達編譯指令,不但費時,而且容易遺漏。即使寫個批次程式,也要隨 時記得納入新的原始檔 由於這些問題的存在,某些原始碼管理系統便因應而生,例如UNIX上的SCCS(Source Code Control System)。Java Compiler具有下面兩個功能,可以在沒有原始碼管理系統的情況 下,也能解決上述問題: 可使用javac *.java來編譯目前目錄下的所有java檔案 編譯A.java時,會自動檢查A所用到的其他class B,比較B.java和B.class的產生時間,如果 B.java比較新則B.java就會被重新編譯 如果應用軟體只有單一的進入點,例如class A的public static void main(String[] argv),則只要編譯A.java就會自動編譯其他需要重新編譯的.java檔。如果應用軟體有兩 個以上的進入點,如網路程式的client端和server端的進入點會不一樣,只要寫個批次檔編 譯相關進入點的.java檔即可。 用Link List實作Stack Link List Stack 示意圖(點圖放大) public class Stack { private Node head; private int size; class Node { Object data; Node next; } public void push(Object s) { Node tmp = new Node(); tmp.next = head; tmp.data = s; size++; head = tmp; } public Object pop() { Object tmp = head.data; head = head.next; size--; return tmp; } } -------------------------------------------------------------------------------- Link List Stack Push Step 1(點圖放大) Link List Stack Push Step 2(點圖放大) Link List Stack Push Step 3(點圖放大) Link List Stack Pop(點圖放大) -------------------------------------------------------------------------------- public class Example { public static void main(String[] argv) { Stack s1 = new Stack(); Stack s2 = new Stack(); s1.push("abc"); s1.push("def"); s2.push("123"); s2.push("456"); } } 用Link List實作Queue public class Queue { private Node head, tail; private int size; class Node { Object data; Node next; } public void put(Object s) { Node tmp = new Node(); tmp.data = s; if (tail != null) { tail.next = tmp; } else { head = tmp; } tail = tmp; size++; } public Object get() { Object tmp = head.data; head = head.next; if (head == null) { tail = null; } size--; return tmp; } } --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.58.22.74







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:iOS站內搜尋

TOP