JavaSE物件導向之類、繼承與多型
你了解類別嗎?
1 在Java中,類別文件是以.java為後綴的程式碼文件,在每個類別文件中最多只允許出現一個public類,當有public類的時候,類別檔案的名稱必須和public類別的名稱相同,若不存在public,則類別檔案的名稱可以為任意的名稱。
2 在類別內部,對於成員變量,如果在定義的時候沒有進行顯示的賦值初始化,則Java會保證類別的每個成員變數都會得到適當的初始化
1)對於 char、short、byte、int、long、float、double等基本資料型別的變數會預設初始化為0(boolean變數預設會被初始化為false);
2)對於引用型別的變量,會預設初始化為null。3 如果沒有顯示地定義建構器,則編譯器會自動建立一個無參考構造器;如果顯示地定義了建構器,編譯器就不會自動新增建構器。請注意,所有的構造器都預設為static的。
-
4 類別實例化物件時的順序
1)當程式執行時,需要產生某個類別的對象,Java執行引擎會先檢查是否載入了這個類,如果沒有加載,則先執行類別的加載再生成對象,如果已經加載,則直接生成對象。
2)在類別的載入過程中,類別的static成員變數會被初始化,另外,如果類別中有static語句區塊,則會執行static語句區塊。 static成員變數和static語句區塊的執行順序同程式碼中的順序一致。
3)在Java中,類別是按需加載,只有當需要用到這個類別的時候,才會加載這個類,並且只會加載一次。
看下面這個範例就明白了:public class Bread { static { System.out.println("Bread is loaded"); } public Bread() { System.out.println("bread"); } public static void main(String[] args) throws ClassNotFoundException { Bread bread1 = new Bread(); Bread bread2 = new Bread(); } }
登入後複製執行這段程式碼就會發現"Bread is loaded"只會被印一次。
4)在產生物件的過程中,會先初始化物件的成員變量,然後再執行建構器。也就是說類別中的變數會在任何方法(包括構造器)呼叫之前初始化,即使變數散步於方法定義之間。public class Test { public static void main(String[] args) { new Meal(); } } class Meal { public Meal() { System.out.println("meal"); } Bread bread = new Bread(); } class Bread { public Bread() { System.out.println("bread"); } }
登入後複製輸出結果為:
bread meal
登入後複製
你了解繼承嗎?
-
1 繼承
1)繼承是所有OOP語言不可缺少的部分,在java中使用extends關鍵字來表示繼承關係。當建立一個類別時,總是在繼承,如果沒有明確指出要繼承的類,就總是隱式地從根類Object進行繼承。例如下面這段程式碼:class Person { public Person() { } } class Man extends Person { public Man() { } }
登入後複製2)類別Man繼承於Person類,這樣一來的話,Person類別稱為父類別(基底類別),Man類別稱為子類別(導出類別)。如果兩個類別存在繼承關係,子類別會自動繼承父類別的方法和變量,在子類別中可以呼叫父類別的方法和變數。
3)在java中,只允許單繼承,也就是說 一個類別最多只能顯示地繼承於一個父類別。但是一個類別卻可以被多個類別繼承,也就是說一個類別可以擁有多個子類別。 2 子類別繼承父類別的屬性
當子類別繼承了某個類別之後,便可以使用父類別中的成員變量,但是並不是完全繼承父類的所有成員變數。具體的原則如下:
1)能夠繼承父類別的public和protected成員變數;不能夠繼承父類別的private成員變數;
2)對於父類別的套件存取權限成員變數,如果子類別和父類別在同一個套件下,則子類別能夠繼承;否則,子類別不能夠繼承;
3)對於子類別可以繼承的父類別成員變量,如果在子類別中出現了同名稱的成員變量,則會發生隱藏現象,也就是子類別的成員變數會屏蔽掉父類別的同名成員變數。如果要在子類別中存取父類別中同名成員變量,則需要使用super關鍵字來進行引用。3 子類別繼承父類別的方法
同樣地,子類別也並不是完全繼承父類別的所有方法。
1)能夠繼承父類別的public和protected成員方法;不能夠繼承父類別的private成員方法;
2)對於父類別的套件存取權成員方法,如果子類別和父類別在同一個套件下,則子類別能夠繼承;否則,子類別不能夠繼承;
3)對於子類別可以繼承的父類別成員方法,如果在子類別中出現了同名稱的成員方法,則稱為覆寫,也就是子類別的成員方法會覆寫父類別的同名成員方法。如果要在子類別中存取父類別中同名成員方法,則需要使用super關鍵字來進行參考。4 注意
隱藏和覆蓋是不同的。
隱藏是針對成員變數和靜態方法的,
而覆寫是針對普通方法的。5 构造器
1)子类是不能够继承父类的构造器,但是要注意的是,如果父类的构造器都是带有参数的,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。
2)如果父类有无参构造器,则在子类的构造器中用super关键字调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。6 super主要有两种用法
1)super.成员变量/super.成员方法;
2)super(parameter1,parameter2....)
第一种用法主要用来在子类中调用父类的同名成员变量或者方法;
第二种主要用在子类的构造器中显示地调用父类的构造器
要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。
你了解多态吗?
1 子类必是父类,所以父类型的引用可以指向子类型的对象。
-
2 动态绑定方法的多种不同版本(即非编译时绑定,而是晚绑定或者动态绑定)
Parent p = new Child(); p.eat();
登入後複製此时Parent和Child中必须都有eat()方法;
即多态进行动态绑定的前提条件是继承,子类必须继承父类的方法,才能使用父类的引用进行方法调用。 3 父类引用能向下转换成子类引用的前提是父类引用指向子类的对象。
4 向下转换后的引用,就可以调用子类特有的方法了。
5 多态的好处,定义方法时,出入参可以申明为父类的类型,传参时,可以传递子类的对象。这样在方法不改变的前提下,就可以扩展子类的种类,添加新的逻辑。
-
6 覆盖方法才会进行动态绑定,而隐藏是不会发生动态绑定的。
1)举例如下public class Test { public static void main(String[] args) { Shape shape = new Circle(); System.out.println(shape.name); // 成员变量(隐藏) shape.printName(); // 静态方法(隐藏) shape.printType(); // 非静态方法(覆盖) } } class Shape { public String name = "shape"; public Shape(){ System.out.println("shape constructor"); } public void printType() { System.out.println("this is shape"); } public static void printName() { System.out.println("shape"); } } class Circle extends Shape { public String name = "circle"; public Circle() { System.out.println("circle constructor"); } public void printType() { System.out.println("this is circle"); } public static void printName() { System.out.println("circle"); } }
登入後複製2)输出结果:
shape constructor circle constructor shape shape this is circle
登入後複製3)原因分析
覆盖受RTTI(Runtime type identification)约束的,而隐藏却不受该约束。也就是说只有覆盖方法才会进行动态绑定,而隐藏是不会发生动态绑定的。在Java中,除了static方法和final方法,其他所有的方法都是动态绑定。因此,就会出现上面的输出结果。
以上是JavaSE物件導向之類、繼承與多型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

在函數繼承中,使用「基底類別指標」和「衍生類別指標」來理解繼承機制:基底類別指標指向派生類別物件時,執行向上轉型,只存取基底類別成員。派生類別指標指向基底類別物件時,執行向下轉型(不安全),必須謹慎使用。

虛基底類別可最佳化虛擬函數表記憶體開銷,透過允許從多個基底類別繼承而無需建立額外虛函數表。在最佳化後程式碼中,形狀基底類別不再有虛擬函數表,圓和矩形類別共享同一個虛擬函數表,從而減少了記憶體消耗。

繼承和多態性會影響類別的耦合度:繼承會增加耦合度,因為衍生類別依賴基底類別。多態性可以降低耦合度,因為物件可以透過虛擬函數和基底類別指標以一致的方式回應訊息。最佳實踐包括謹慎使用繼承、定義公共介面、避免在基底類別中新增資料成員,以及透過依賴注入解耦類別。實戰案例顯示如何使用多態性和依賴注入來降低銀行帳戶應用程式中的耦合度。

繼承錯誤調試技巧:確保正確的繼承關係。使用偵錯器逐步執行程式碼,檢查變數值。確保正確使用virtual修飾符。檢查隱藏的繼承帶來的菱形繼承問題。檢查抽象類別中未實現的純虛函數。

C++函式繼承詳解:掌握「is-a」和「has-a」關係什麼是函式繼承?函數繼承是C++中一種將衍生類別中定義的方法與基底類別中定義的方法關聯起來的技術。它允許衍生類別存取和重寫基底類別的方法,從而擴展了基底類別的功能。 「is-a」和「has-a」關係在函數繼承中,「is-a」關係指派生類別是基底類別的子類型,也就是說,衍生類別「繼承」了基底類別的特性和行為。 「has-a」關係指派生類別包含對基底類別物件的參考或指針,也就是說,衍生類別「擁有」了基底類別物件。語法以下是如何實作函數繼承的語法:classDerivedClass:pu

什麼是物件導向程式設計?物件導向程式設計(OOP)是一種程式設計範式,它將現實世界中的實體抽象化為類,並使用物件來表示這些實體。類別定義了物件的屬性和行為,而物件則實例化了類別。 OOP的主要優點在於它可以使程式碼更易於理解、維護和重複使用。 OOP的基本概念OOP的主要概念包括類別、物件、屬性和方法。類別是物件的藍圖,它定義了物件的屬性和行為。物件是類別的實例,它具有類別的所有屬性和行為。屬性是物件的特徵,它可以儲存資料。方法是物件的函數,它可以對物件的資料進行操作。 OOP的優點OOP的主要優點包括:可重複使用性:OOP可以讓程式碼更

在以下情況下不應使用C++函數繼承:衍生類別需要不同實作時,應建立具有不同實作的新函數。衍生類別不需要函數時,應宣告為一個空類別或使用私有、未實作的基底類別成員函數來停用函數繼承。函數不需要繼承時,應使用其他機制(例如範本)來實作程式碼重用。

介面:無實作的契約介面在Java中定義了一組方法簽名,但不提供任何具體實作。它充當一種契約,強制實作該介面的類別實現其指定的方法。介面中的方法是抽象方法,沒有方法體。程式碼範例:publicinterfaceAnimal{voideat();voidsleep();}抽象類別:部分實作的藍圖抽象類別是一種父類,它提供了一個部分實現,可以被它的子類別繼承。與介面不同,抽象類別可以包含具體的實作和抽象方法。抽象方法是用abstract關鍵字聲明的,並且必須被子類別覆蓋。程式碼範例:publicabstractcla
