如果你之前從來沒有使用過面向對象編程語言,那麼在學習Java之前需要先理解幾個有關面向對象編程的基本概念。這篇教程將會向你介紹對象、類、集成、介面和包的概念,以及這些概念是如何與現實世界相關聯,並介紹這些概念在Java語言中的體現。 ...
如果你之前從來沒有使用過面向對象編程語言,那麼在學習Java之前需要先理解幾個有關面向對象編程的基本概念。這篇教程將會向你介紹對象、類、集成、介面和包的概念,以及這些概念是如何與現實世界相關聯,並介紹這些概念在Java語言中的體現。
一.對象
對象將狀態和行為綁定在一起,它可以被用來模擬你能列舉出的現實世界中的任何實體。這一小節將會解釋如何在對象中表示狀態和行為,介紹封裝的概念,並解釋這種軟體設計方式的好處。
對象是理解面向對象技術的關鍵。環顧四周,你會發現許多現實世界中的對象:狗、桌子、電視機、自行車等。現實世界中的對象都有兩個特征:它們都有狀態和行為。狗有自己的狀態(名字、顏色、品種、是否饑餓等)和行為(叫、跑、吃等)。自行車也有狀態(當前齒輪、當前轉速和當前速度等)和行為(換擋、變速和剎車等)。識別現實對象的狀態和行為是開始使用面向對象編程概念的好方法。
現在花點時間來觀察附近的真實物體。對於看到的每個對象,請問自己兩個問題:這個對象可能存在哪些狀態?這個對象可以執行哪些行為?你會註意到現實世界中的物體的複雜程度各不相同。桌面上的臺燈可能只有兩種狀態(開和關)和兩種可能的行為(打開和關閉),但電視可能有更多的狀態(開,關,當前音量,當前電臺)和更多的行為(打開,關閉,調大音量,調小音量,搜索等)。你可能還會註意到,某些對象也會包含其他對象。
編程中的對象在概念上類似於現實世界的對象:它們也包括狀態和行為。對象將其狀態存儲在域(編程語言中的變數)中,並通過方法(編程語言中的函數)公開其行為。方法對對象的內部狀態進行操作,並作為對象和對象通信的主要機制。隱藏內部狀態並要求通過對象的方法執行所有交互稱為封裝,這正是面向對象編程的基本原則。
即使對象向外界提供了改變其狀態的方法,它仍然控制著外界如何來使用這些方法。例如,如果自行車只有6個齒輪,換檔的方法可以拒絕任何小於1或大於6的值。
將代碼與對象綁定有許多好處,包括:
- 模塊化:對象的源代碼可以獨立於其他對象的源代碼進行編寫和維護。一旦創建,對象就可以很容易地在系統內部傳遞。
- 信息隱藏:儘管對象通過方法與外界交互,但其內部實現的細節仍然對外界隱藏。
- 代碼重用:如果一個對象已經存在(可能由另一個軟體開發人員編寫),那麼你可以在程式中使用該對象。
- 可插拔和便於調試:如果某個特定對象出現問題,你可以簡單地將其從應用程式中刪除,並插入另一個對象作為替換對象。這類似於解決現實世界中的機械問題。如果螺絲壞了,你就換掉它,而不是整台機器。
二.類
類是創建對象的藍圖或原型。本節定義了一個模擬現實世界對象的狀態和行為的類。我將利用它來展示一個簡單的類如何能夠模擬狀態和行為。
在現實世界中,經常會發現許多相同類型的對象。可能存在數千輛自行車,它們都具有相同的品牌和型號。每輛自行車都是使用相同的原型構建的,因此包含相同的組件。在面向對象的術語中,我們將每輛自行車稱為自行車類的一個實例。
下麵的Bicycle類是自行車的一種實現方式:
class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
void printStates() {
System.out.println("cadence:" + cadence + " speed:" + speed + " gear:" + gear);
}
}
你可能對Java的語法還不瞭解,但是這個類的定義是基於我們之前討論的自行車對象的。cadence,speed和gear域表示了對象的狀態,changeCadence,changeGear,speedUp等方法定義了對象與外界的聯繫。
你可能已經註意到Bicycle類不包含main方法,這是因為它不是一個完整的應用程式。它只是可能在應用程式中使用到的自行車的原型。創建和使用新Bicycle對象的責任屬於應用程式中的其他類。
下麵的BicycleDemo類創造了兩個Bicycle對象並調用了它們的方法:
class BicycleDemo {
public static void main(String[] args) {
// Create two different Bicycle objects
Bicycle bike1 = new Bicycle();
Bicycle bike2 = new Bicycle();
// Invoke methods on those objects
bike1.changeCadence(50);
bike1.speedUp(10);
bike1.changeGear(2);
bike1.printStates();
bike2.changeCadence(50);
bike2.speedUp(10);
bike2.changeGear(2);
bike2.changeCadence(40);
bike2.speedUp(10);
bike2.changeGear(3);
bike2.printStates();
}
}
這個樣例的輸出列印了兩輛自行車最終的轉速,速度和檔位:
cadence:50 speed:10 gear:2
cadence:40 speed:20 gear:3
三.繼承
繼承為組織和構建軟體提供了強大而自然的機制。本節介紹了類如何從超類繼承狀態和行為,並解釋瞭如何使用Java語言提供的語法從一個類派生出另一個類。
有些不同種類的物體具備某些相同的特性。例如,公路自行車和雙人自行車都具有自行車的特性(速度,轉速和檔位)。然而,每種自行車還具有與眾不同的其他功能:雙人自行車有兩個座位和兩套車把,公路自行車有把手。
面向對象編程允許類從其他類繼承通用的狀態和行為。在這個例子中,Bicycle變成了RoadBike和TandemBike的超類。在Java編程語言中,允許每個類具有一個直接超類,並且每個超類都有可能存在無限數量的子類。
定義子類的語法很簡單。在你要定義的類名後面使用extends關鍵字,再跟上要繼承的類的名字:
class MountainBike extends Bicycle {
// new fields and methods defining a mountain bike would go here
}
MountainBike具有和Bicycle相同的域和方法,並且允許其代碼專註於獨特的功能,這使得子類的代碼易於閱讀。但是,必須註意正確記錄每個超類定義的狀態和行為,因為該代碼不會出現在每個子類的源文件中。
四.介面
介面是類與外部世界之間的契約。當類實現介面時,它承諾提供由該介面發佈的行為。本節定義了一個簡單的介面,並解釋了任何實現了它的類所需要做的必要的更改。
正如之前瞭解的那樣,對象通過它們公開的方法來進行與外部世界的交互。方法形成對象與外界的介面。例如,電視機正面的按鈕是你與塑料外殼內的電線之間的介面,你可以使用電源鍵來打開和關閉電視。
在最常見的形式中,介面是一組沒有方法體的方法。自行車的行為(如果指定為介面)可能如下所示:
interface Bicycle {
void changeCadence(int newValue);
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
要實現這個介面,在你要定義的類名後面使用implements關鍵字,再跟上要實現的介面的名字:
class ACMEBicycle implements Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
void printStates() {
System.out.println("cadence:" + cadence + " speed:" + speed + " gear:" + gear);
}
}
實現介面就相當於類在履行和介面的承諾。介面形成了類和外部世界之間的契約,而這個契約在編譯時由編譯器進行檢測。如果類聲稱要實現一個介面,那麼該類必須提供介面定義的所有方法,然後該類才能成功編譯。
五.包
包是用於以邏輯方式組織類和介面的命名空間。將代碼放入包中可以使大型軟體項目更易於管理。本節解釋了這樣做的原因,並向您介紹Java平臺提供的應用程式編程介面(API)。
包是一個命名空間,用於組織一組相關的類和介面。從概念上講,可以將包視為與電腦上的文件夾。因為用Java編程語言編寫的應用可能由數百或數千個單獨的類組成,所以通過將相關的類和介面放入包中來組織應用的結構是很有意義的。
Java平臺提供了一個很大的類庫(一組包),該庫稱為“應用程式編程介面”,簡稱“API”。它代表了最常用於通用編程的任務。例如,String對象包含字元串的狀態和行為; 一個File對象允許程式員輕鬆地創建、刪除、檢查、比較或修改文件系統上的文件; 一個Socketobject允許創建和使用網路套接字。有數以千計的類可供選擇。這使程式員可以專註於特定應用程式的設計,而不是設計其工作所需的基礎結構。
在Java Platform API Specification中包含了所有的包,介面,類的完整列表。作為程式員,它將成為最重要的參考文檔。