Java :: public/建構式/重載

文章推薦指數: 80 %
投票人數:10人

建構式是與類別名稱同名,無需宣告傳回型態的方法。

例如:. public class Some { private int a ... OPENHOME.CC Java |Java平台概論 Java版本遷移 JDK規範與實作 JVM、JRE與JDK |路徑/套件/模組 Hello,Java JDK/JRE/類別版本 類別/原始碼路徑 package與import 初探模組 |語法基礎 型態 變數 運算子 型態轉換 if/else、switch for、while迴圈 |類別與物件 定義類別 使用Scanner、BigDecimal 基本型態包裹器 陣列 字串 Java與Unicode |封裝 流程與資料的封裝 public/建構式/重載 this與static 不定長度引數/內部類別 資料載體與record |繼承 共同行為與isa 重新定義/abstract protected/super final/Object/instanceof sealed類別 |介面 定義行為外觀 解決需求變化 介面語法細節 使用enum列舉 sealed介面 |例外 try/catch例外處理 要抓還是要拋? 堆疊追蹤與assert finally資源關閉 |泛型 定義與使用泛型 Producerextends Consumersuper |Lambda 初試Lambda Lambda運算式與函式介面 this與final 方法與建構式參考 GitHub Twitter Facebook LinkedIn 2DDesigns 3DDesigns Tags BuiltwithbyHugo HOME> Java> 封裝> public/建構式/重載 public權限修飾 關於建構式 重載 polymorphism adhocpolymorphism public/建構式/重載 May28,2022 在〈流程與資料的封裝〉的CashCard類別是定義在cc.openhome套件,假設現在為了管理上的需求,要將CashCard類別定義至cc.openhome.virtual套件。

public權限修飾 除了原始碼與位元碼的資料夾需求必須符合套件階層之外,原始碼內容也得作些修改: packagecc.openhome.virtual; classCashCard{ ... } 這一改可不得了,你發現使用到CashCard的程式碼都出錯了: 宣告為private的成員表示為類別私有,使用者無法在其他類別的程式碼中直接存取。

如果沒有宣告權限修飾的成員,只有在相同套件的類別程式碼中,才可以直接存取,也就是「套件範圍權限」。

如果不同套件的類別程式碼中,想要直接存取,就會出現上圖的錯誤訊息。

如果想在其他套件的類別程式碼中存取某套件的類別或物件成員,則該類別或物件成員必須是公開成員,要使用public加以修飾。

例如: packagecc.openhome.virtual; publicclassCashCard{ ...略 publicCashCard(Stringnumber,intbalance,intbonus){ ...略 } publicvoidstore(intmoney){ ...略 } publicvoidcharge(intmoney){ ...略 } publicintexchange(intbonus){ ...略 } publicintgetBalance(){ returnbalance; } publicintgetBonus(){ returnbonus; } publicStringgetNumber(){ returnnumber; } } 你可以宣告類別為public,這表示它是個公開類別,可以在其它套件的類別中使用,你可以在建構式上宣告public,這表示其他套件中的類別可以直接呼叫這個建構式,你可以在方法上宣告public,這表示其他套件的方法可以直接呼叫這個方法。

如果你願意,也可以在物件資料成員上宣告public。

〈package與import〉談過,套件管理還有權限管理上的概念,沒有定義任何權限關鍵字時,就是套件權限。

如果類別上沒有宣告public權限關鍵字,類別中的方法宣告就算是public,也等於是套件權限了,因為類別本身是套件權限,其他套件根本就無法使用類別了,更別說當中定義的方法。

關於建構式 在定義類別時,可以使用建構式定義物件建立的初始流程。

建構式是與類別名稱同名,無需宣告傳回型態的方法。

例如: publicclassSome{ privateinta=10;//指定初始值 privateStringtext;//預設值null publicSome(inta,Stringtext){ this.a=a; this.text=text; } ... } 若如下建立Some物件,成員a與text會初始兩次: varsome=newSome(10,"sometext"); 建構物件時,資料成員就會初始化,如果沒有指定初始值,會使用預設值初始化,預設值如下表所示: 型態 初始值 byte 0 short 0 int 0 long 0L float 0.0F double 0.0D char \u0000(空字元) boolean false 類別 null 使用new建構Some物件時,a與text分別先初始為10與null,之後會再經由建構式流程,設定為建構式參數的值。

如果定義類別時,沒有撰寫任何建構式,編譯器會自動加入一個無參數、內容為空的建構式。

例如若如下撰寫: publicclassSome{ } 將這個類別編譯後的位元碼反組譯,你會看到: publicclassSome{ publicSome(){ } } 正因為編譯器會在沒有撰寫任何建構式時,自動加入預設建構式(Defaultconstructor),才可以在沒有撰寫任何建構式時,也可以如下以無引數方式呼叫建構式: varsome=newSome(); 只有編譯器自動加入的建構式,才稱為預設建構式,如果你自行撰寫無參數、沒有內容的建構式,就不稱為預設建構式了,雖然只是名詞定義,不過認證考試時要區別一下兩者的不同。

如果自行撰寫了建構式,編譯器就不會自動建立預設建構式。

如果你這麼寫: publicclassSome{ publicSome(inta){ } } 那就只有一個具int參數的建構式,所以就不可以newSome()來建構物件,而必須使用newSome(1)的形式來建構物件。

重載 視使用情境或條件的不同,建構物件時也許希望有對應的初始流程,你可以定義多個建構式,只要參數型態或個數不同,這稱為重載(Overload)建構式。

例如: publicclassSome{ privateinta=10; privateStringtext="n.a."; publicSome(inta){ if(a>0){ this.a=a; } } publicSome(inta,Stringtext){ if(a>0){ this.a=a; } if(text!=null){ this.text=text; } } ... } 在這個程式碼片段中,建構時有兩種選擇,一是使用newSome(100)的方式,另一個是使用newSome(100,"sometext")的方式。

有些場合建議,如果定義了有參數的建構式,也可以加入無參數建構式,即使內容為空也無所謂,這是為了日後使用上的彈性,例如運用反射(Reflection)機制生成物件的需求,或者是繼承時呼叫父類別建構式時的方便。

定義方法時也可以進行重載,可為類似功能的方法提供統一名稱,但根據參數型態或個數的不同呼叫對應的方法。

以String類別為例,valueOf方法就提供了多個版本: publicstaticStringvalueOf(booleanb) publicstaticStringvalueOf(charc) publicstaticStringvalueOf(char[]data) publicstaticStringvalueOf(char[]data,intoffset,intcount) publicstaticStringvalueOf(doubled) publicstaticStringvalueOf(floatf) publicstaticStringvalueOf(inti) publicstaticStringvalueOf(longl) publicstaticStringvalueOf(Objectobj) 雖然呼叫的方法名稱都是valueOf,但根據傳遞的引數型態不同,會呼叫對應的方法,例如呼叫String.valueOf,因為10是int型態,會執行valueOf(inti)的版本,若是String.valueOf(10.12),因為10.12是double型態,會執行valueOf(doubled)的版本。

方法重載讓程式設計人員不用苦惱方法名稱的設計,可用一致的名稱來呼叫類似功能的方法,方法重載可根據傳遞引數的型態不同,也可根據參數列個數的不同來設計方法重載。

例如: publicclassSomeClass{ publicvoidsomeMethod(){ } publicvoidsomeMethod(inti){ } publicvoidsomeMethod(floatf){ } publicvoidsomeMethod(inti,floatf){ } } 傳回值型態不可作為方法重載依據,例如以下方法重載並不正確,編譯器會將兩個someMethod視為重複定義而編譯失敗: publicclassSome{ publicintsomeMethod(inti){ return0; } publicdoublesomeMethod(inti){ return0.0; } }



請為這篇文章評分?