Java面向對象設計
本教程將通過示例瞭解Java中面向對象(OOP)的概念。討論面向對象編程的特性,以及編寫面向對象程序包括創建類,並從這些類創建對象,以及創建應用程序,這些應用程序是使用這些對象的獨立可執行程序。
如果以前從未使用過面向對象的編程語言,在開始編寫任何代碼之前,您需要學習一些基本概念。本課將向您介紹對象,類,繼承,接口和包。在這些概念如何與真實世界相關,同時提供Java編程語言的語法介紹。
對象是什麼?
對象是相關狀態和行爲的軟件包。軟件對象通常用於模擬在日常生活中發現的真實世界對象。本課解釋如何在對象中表示狀態和行爲,介紹數據封裝的概念,並解釋以這種方式設計軟件的好處。
更多關於對象,可點擊以下鏈接瞭解 -
類是什麼?
類是創建對象的藍圖或原型。這個部分定義了一個模型化真實世界對象的狀態和行爲的類。 它有意地專注於基礎,顯示一個簡單的類如何幹淨地建模狀態和行爲。
更多關於類的介紹,可點擊以下鏈接瞭解 -
繼承是什麼?
繼承提供了一個強大和自然的機制來組織和結構化軟件。本節介紹類如何從其父類繼承狀態和行爲,並解釋如何使用Java編程語言提供的簡單語法從另一個類派生一個類。
更多關於繼承的介紹,可點擊以下鏈接瞭解 -
接口是什麼?
接口是類和外部世界之間的契約。當一個類實現一個接口時,它承諾提供由該接口發佈的行爲。本節定義一個簡單的接口,並解釋實現它的任何類的必要的更改。
更多關於接口的介紹,可點擊以下鏈接瞭解 -
包是什麼?
包是以邏輯方式組織類和接口的命名空間。將代碼放入包中使得大型軟件項目更容易管理。 本節解釋爲什麼包是這麼有用,並介紹由Java平臺提供的應用程序編程接口(API)。
更多關於包的介紹,可點擊以下鏈接瞭解 -
類是定義對象的數據字段和方法的模板,藍圖或約定。對象是類的實例。一個類可以創建多個實例。Java類使用變量來定義數據字段和方法來定義操作。此外,類提供了一種特殊類型的方法,稱爲構造函數,調用它們來創建一個新對象。構造函數可以執行任何操作,但構造函數一般設計爲執行初始化操作,例如:初始化對象的數據字段。
參考以下圖,類可被實例化爲一個個的對象 -
對象由屬性和方法組成。 屬性是定義對象的特徵; 屬性中包含的值將同一個類的對象區分開來。爲了更好地理解這一點,以手機(Mobile
)作爲一個對象。手機(Mobile
)具有像模型,製造商,成本,操作系統等特性。因此,如果創建「華爲」手機對象和「IPhone」手機對象,它們的特性是不一樣的,因此每個對象是不一樣的。對象的屬性的值也稱爲對象的狀態。
Java面向對象編程有三個主要特點。
- 封裝
- 繼承
- 多態性
我們對上面每個特性作更詳細討論和學習。
封裝
封裝意味着將所有變量(實例變量)和方法放在一個稱爲類的單元中,在對象內隱藏數據和方法。 封裝提供了保證數據和方法免於被意外更改的安全性。程序員有時將封裝稱爲使用「黑盒」,或者可以使用而不考慮內部實現機制。 程序員可以訪問和使用黑盒中包含的方法和數據,但不能更改它們。下面示例顯示了Mobile
類和屬性,在使用構造函數參數創建對象時設置一次對象信息。可以使用具有公共(public
)訪問修飾符的getXXX()
方法來訪問屬性。
package oopsconcept;
public class Mobile {
private String manufacturer;
private String operating_system;
public String model;
private int cost;
//Constructor to set properties/characteristics of object
Mobile(String man, String o,String m, int c){
this.manufacturer = man;
this.operating_system=o;
this.model=m;
this.cost=c;
}
//Method to get access Model property of Object
public String getModel(){
return this.model;
}
// We can add other method to get access to other properties
}
繼承
面向對象程序的一個重要特性是繼承 - 創建一個新類時共享現有類的屬性和方法。繼承主要用於代碼可重用性。所以利用已有的類並作進一步擴展即可。這就是提高代碼的可重用性的一種辦法。一般來說,一個定義可以告訴從已有的類派生一個新類,這種實現稱爲繼承。可以查看下面的繼承概念示例。這裏已有上面的步中創建的Mobile
類,它被其他特定類如:Android
類和Blackberry
類擴展。
Android.java 代碼如下 -
package oopsconcept;
public class Android extends Mobile{
//Constructor to set properties/characteristics of object
Android(String man, String o,String m, int c){
super(man, o, m, c);
}
//Method to get access Model property of Object
public String getModel(){
return "This is Android Mobile- " + model;
}
}
Blackberry.java 代碼如下 -
package oopsconcept;
public class Blackberry extends Mobile{
//Constructor to set properties/characteristics of object
Blackberry(String man, String o,String m, int c){
super(man, o, m, c);
}
public String getModel(){
return "This is Blackberry-"+ model;
}
}
多態性
在Java核心中,多態(Polymorphism)是一個容易理解的概念。 多態性定義是:Poly表示許多,morphos表示形式。它描述了允許在基於上下文的不同情況下正確解釋相同字或符號的語言的特徵。在Java中有兩種類型的多態性。 例如,在英語中,動詞「run
」表示不同的東西,如果在「足跡」,「商業」或「電腦」這個東西關聯。那麼理解「run
」的含義應該是基於與它使用的其他詞。面向對象的程序可編寫使用相同名稱的方法,但在不同的上下文中執行不同的工作。 Java提供了兩種實現多態的方法。
1. 靜態多態性(編譯時多態性/方法重載):
通過改變方法名稱和參數來執行不同方法實現的能力被稱爲方法重載。在下面的程序中,有三個打印(print()
)方法,每個方法有不同的參數。當要正確重載一個方法時,可以調用它提供不同的參數列表,並執行相應的方法版本。
package oopsconcept;
class Overloadsample {
public void print(String s){
System.out.println("First Method with only String- "+ s);
}
public void print (int i){
System.out.println("Second Method with only int- "+ i);
}
public void print (String s, int i){
System.out.println("Third Method with both- "+ s + "--" + i);
}
}
public class PolymDemo {
public static void main(String[] args) {
Overloadsample obj = new Overloadsample();
obj.print(10);
obj.print("Amit");
obj.print("Hello", 100);
}
}
執行上面代碼,輸出結果如下 -
2. 動態多態性(運行時多態性/方法覆蓋)
當通過擴展現有類創建子類時,新子類包含在原始超類中定義的數據和方法。換句話說,任何子類對象都具有其父對象的所有屬性。然而,有時,超類數據字段和方法不完全適合於子類對象; 在這些情況下可考慮覆蓋父類成員。下面舉個例子說明繼承。
package oopsconcept;
public class OverridingDemo {
public static void main(String[] args) {
//Creating Object of SuperClass and calling getModel Method
Mobile m = new Mobile("Nokia", "Win8", "Lumia",10000);
System.out.println(m.getModel());
//Creating Object of Sublcass and calling getModel Method
Android a = new Android("Samsung", "Android", "Grand",30000);
System.out.println(a.getModel());
//Creating Object of Sublcass and calling getModel Method
Blackberry b = new Blackberry("BlackB", "RIM", "Curve",20000);
System.out.println(b.getModel());
}
}
抽象
所有編程語言都提供抽象。可以說,能夠解決的問題的複雜性與抽象的種類和質量直接相關。面向對象編程的一個基本要素是抽象。人類通過抽象來管理複雜性。當你開車時,不必關心汽車的確切內部工作(除非你是一個技工)。關心的是通過其接口,如方向盤,制動踏板,加速踏板等與汽車交互。各種汽車製造商有不同的實施汽車工作,但其基本接口沒有改變(即仍然使用方向盤,剎車踏板,加速踏板等與汽車互動)。 因此,對汽車的知識是抽象的。
管理抽象的強大方法是通過使用層次化分類。這允許分層複雜系統的語義,將它們分成更易於管理的部分。從外面,一輛汽車是一個單一的對象。汽車由幾個子系統組成:轉向,制動器,音響系統,安全帶,暖氣,蜂窩電話等。反過來,這些子系統中的每一個由更專門的單元組成。 例如,聲音系統由無線電,CD播放器和/或磁帶播放器組成。關鍵是通過使用分層抽象來管理汽車(或任何其他複雜系統)的複雜性。
抽象類是不完整的東西,不能創建抽象類的實例。如果想使用它,需要通過擴展它來完成或具體的實現。如果一個類不包含任何抽象方法,並且實現了所有抽象方法繼承自已實現或擴展的抽象類或接口,那麼它被稱爲具體類。順便說一下,Java有抽象類的概念,抽象方法,但是變量不能在Java中抽象。
讓我們舉一個名爲Vehicle
的Java抽象類的例子。當創建一個類叫Vehicle
,知道應該有像start()
和Stop()
的方法,但不知道每個車輛的啓動和停止機制,因爲可以有不同的啓動和停止機制,例如:可以通過按按鈕啓動。
抽象的優點是:一個新類型的車輛只需要創建一個新類,擴展 VehicleAbstract
類並實現它的方法:啓動-start()
和停止-stop()
方法的接口都是一樣的。
package oopsconcept;
public abstract class VehicleAbstract {
public abstract void start();
public void stop(){
System.out.println("Stopping Vehicle in abstract class");
}
}
class TwoWheeler extends VehicleAbstract{
@Override
public void start() {
System.out.println("Starting Two Wheeler");
}
}
class FourWheeler extends VehicleAbstract{
@Override
public void start() {
System.out.println("Starting Four Wheeler");
}
}
package oopsconcept;
public class VehicleTesting {
public static void main(String[] args) {
VehicleAbstract my2Wheeler = new TwoWheeler();
VehicleAbstract my4Wheeler = new FourWheeler();
my2Wheeler.start();
my2Wheeler.stop();
my4Wheeler.start();
my4Wheeler.stop();
}
}
執行上面代碼,輸出結果如下 -