Java 系列教程:
如果你之前從來沒有使用過面向對象編程語言,那么在學習Java之前需要先理解幾個有關面向對象編程的基本概念。這篇教程將會向你介紹對象、類、集成、接口和包的概念,以及這些概念是如何與現實世界相關聯,并介紹這些概念在Java語言中的體現。
一.對象
對象將狀態和行為綁定在一起,它可以被用來模擬你能列舉出的現實世界中的任何實體。這一小節將會解釋如何在對象中表示狀態和行為,介紹封裝的概念,并解釋這種軟件設計方式的好處。
對象是理解面向對象技術的關鍵。環顧四周,你會發現許多現實世界中的對象:狗、桌子、電視機、自行車等?,F實世界中的對象都有兩個特征:它們都有狀態和行為。狗有自己的狀態(名字、顏色、品種、是否饑餓等)和行為(叫、跑、吃等)。自行車也有狀態(當前齒輪、當前轉速和當前速度等)和行為(換擋、變速和剎車等)。識別現實對象的狀態和行為是開始使用面向對象編程概念的好方法。
現在花點時間來觀察附近的真實物體。對于看到的每個對象,請問自己兩個問題:這個對象可能存在哪些狀態?這個對象可以執行哪些行為?你會注意到現實世界中的物體的復雜程度各不相同。桌面上的臺燈可能只有兩種狀態(開和關)和兩種可能的行為(打開和關閉),但電視可能有更多的狀態(開,關,當前音量,當前電臺)和更多的行為(打開,關閉,調大音量,調小音量,搜索等)。你可能還會注意到,某些對象也會包含其他對象。
編程中的對象在概念上類似于現實世界的對象:它們也包括狀態和行為。對象將其狀態存儲在域(編程語言中的變量)中,并通過方法(編程語言中的函數)公開其行為。方法對對象的內部狀態進行操作,并作為對象和對象通信的主要機制。隱藏內部狀態并要求通過對象的方法執行所有交互稱為封裝,這正是面向對象編程的基本原則。
即使對象向外界提供了改變其狀態的方法,它仍然控制著外界如何來使用這些方法。例如,如果自行車只有6個齒輪,換檔的方法可以拒絕任何小于1或大于6的值。
將代碼與對象綁定有許多好處,包括:
模塊化:對象的源代碼可以獨立于其他對象的源代碼進行編寫和維護。一旦創建,對象就可以很容易地在系統內部傳遞。
信息隱藏:盡管對象通過方法與外界交互,但其內部實現的細節仍然對外界隱藏。
代碼重用:如果一個對象已經存在(可能由另一個軟件開發人員編寫),那么你可以在程序中使用該對象。
可插拔和便于調試:如果某個特定對象出現問題,你可以簡單地將其從應用程序中刪除,并插入另一個對象作為替換對象。這類似于解決現實世界中的機械問題。如果螺絲壞了,你就換掉它,而不是整臺機器。
二.類
類是創建對象的藍圖或原型。本節定義了一個模擬現實世界對象的狀態和行為的類。我將利用它來展示一個簡單的類如何能夠模擬狀態和行為。
在現實世界中,經常會發現許多相同類型的對象??赡艽嬖跀登лv自行車,它們都具有相同的品牌和型號。每輛自行車都是使用相同的原型構建的,因此包含相同的組件。在面向對象的術語中,我們將每輛自行車稱為自行車類的一個實例。
下面的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允許創建和使用網絡套接字。有數以千計的類可供選擇。這使程序員可以專注于特定應用程序的設計,而不是設計其工作所需的基礎結構。