Java物件導向設計


本教學將通過範例了解Java中物件導向(OOP)的概念。討論物件導向程式設計的特性,以及編寫物件導向程式包括建立類,並從這些類建立物件,以及建立應用程式,這些應用程式是使用這些物件的獨立可執行程式。

如果以前從未使用過物件導向的程式設計語言,在開始編寫任何程式碼之前,您需要學習一些基本概念。本課將向您介紹物件,類,繼承,介面和包。在這些概念如何與真實世界相關,同時提供Java程式設計語言的語法介紹。

物件是什麼?

物件是相關狀態和行為的軟體包。軟體物件通常用於模擬在日常生活中發現的真實世界物件。本課解釋如何在物件中表示狀態和行為,介紹資料封裝的概念,並解釋以這種方式設計軟體的好處。
更多關於物件,可點選以下連結了解 -

類是什麼?

類是建立物件的藍圖或原型。這個部分定義了一個模型化真實世界物件的狀態和行為的類。 它有意地專注於基礎,顯示一個簡單的類如何乾淨地建模狀態和行為。
更多關於類的介紹,可點選以下連結了解 -

繼承是什麼?

繼承提供了一個強大和自然的機制來組織和結構化軟體。本節介紹類如何從其父類別繼承狀態和行為,並解釋如何使用Java程式設計語言提供的簡單語法從另一個類派生一個類。
更多關於繼承的介紹,可點選以下連結了解 -

介面是什麼?

介面是類和外部世界之間的契約。當一個類實現一個介面時,它承諾提供由該介面發布的行為。本節定義一個簡單的介面,並解釋實現它的任何類的必要的更改。
更多關於介面的介紹,可點選以下連結了解 -

包是什麼?

包是以邏輯方式組織類和介面的名稱空間。將程式碼放入包中使得大型軟體專案更容易管理。 本節解釋為什麼包是這麼有用,並介紹由Java平台提供的應用程式程式設計介面(API)。
更多關於包的介紹,可點選以下連結了解 -

類是定義物件的資料欄位和方法的模板,藍圖或約定。物件是類的範例。一個類可以建立多個範例。Java類使用變數來定義資料欄位和方法來定義操作。此外,類提供了一種特殊型別的方法,稱為建構函式,呼叫它們來建立一個新物件。建構函式可以執行任何操作,但建構函式一般設計為執行初始化操作,例如:初始化物件的資料欄位。
參考以下圖,類可被範例化為一個個的物件 -

物件由屬性和方法組成。 屬性是定義物件的特徵; 屬性中包含的值將同一個類的物件區分開來。為了更好地理解這一點,以手機(Mobile)作為一個物件。手機(Mobile)具有像模型,製造商,成本,作業系統等特性。因此,如果建立「華為」手機物件和「IPhone」手機物件,它們的特性是不一樣的,因此每個物件是不一樣的。物件的屬性的值也稱為物件的狀態。

Java物件導向程式設計有三個主要特點。

  1. 封裝
  2. 繼承
  3. 多型性

我們對上面每個特性作更詳細討論和學習。

封裝

封裝意味著將所有變數(範例變數)和方法放在一個稱為類的單元中,在物件內隱藏資料和方法。 封裝提供了保證資料和方法免於被意外更改的安全性。程式員有時將封裝稱為使用「黑盒」,或者可以使用而不考慮內部實現機制。 程式員可以存取和使用黑盒中包含的方法和資料,但不能更改它們。下面範例顯示了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();
    }
}

執行上面程式碼,輸出結果如下 -