你好!你有沒有想過為什麼 Java 是這樣設計的?從某種意義上說,您基於它們創建類別 - 物件、類別具有方法等。但是為什麼語言的結構使得程式由類別和物件組成,而不是由其他東西組成呢?為什麼「對象」的概念被發明並放在最前線?所有語言都是這樣運作的嗎?如果不是,它為 Java 帶來了什麼好處?正如您所看到的,有很多問題:)讓我們在今天的講座中嘗試回答每個問題。
Kristen Nygaard 和 Ole Johan Dahl - Simula 的創作者
從程式設計標準來看,Simula 似乎是一門古老的語言,但它們與 Java 的「家族」聯繫是肉眼可見的。最有可能的是,您可以輕鬆閱讀上面寫的程式碼並一般性地解釋它的作用:)
物件導向程式設計原則:
什麼是物件導向程式設計(OOP)
當然,Java 由物件和類別組成是有原因的。這不是其創造者的心血來潮,甚至不是他們的發明。還有許多其他基於物件的語言。第一種此類語言稱為 Simula,它於 20 世紀 60 年代在挪威發明。除此之外,Simula 還引入了「類別」和「方法」的概念。Begin
Class Rectangle (Width, Height); Real Width, Height;
Begin
Real Area, Perimeter;
Procedure Update;
Begin
Area := Width * Height;
OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
Perimeter := 2*(Width + Height);
OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
End of Update;
Update;
OutText("Rectangle created: "); OutFix(Width,2,6);
OutFix(Height,2,6); OutImage;
End of Rectangle;
Rectangle Class ColouredRectangle (Color); Text Color;
Begin
OutText("ColouredRectangle created, color = "); OutText(Color);
OutImage;
End of ColouredRectangle;
Ref(Rectangle) Cr;
Cr :- New ColouredRectangle(10, 20, "Green");
End;
程式碼範例取自文章Simula - 50 年的 OOP。正如你所看到的,Java和它的祖先並沒有太大的不同:)這是因為Simula的出現標誌著一個新概念的誕生——物件導向程式設計。維基百科給出了以下 OOP 的定義:物件導向程式設計(OOP)是一種基於將程式表示為物件集合的程式設計方法,每個物件都是特定類別的實例,並且這些類別形成繼承層次結構。在我看來,這是非常成功的。您最近開始學習 Java,但其中幾乎沒有您不熟悉的單字:) 如今,OOP 是最常見的程式設計方法。除了 Java 之外,OOP 原理也用在許多您可能聽過的流行語言中。它們是 C++(電腦遊戲開發人員積極使用)、Objective-C 和 Swift(為 Apple 設備編寫程式)、Python(機器學習領域需求最大)、PHP(最受歡迎的 Web 開發語言之一)、 JavaScript(簡單地說他們不做的事情)和許多其他。實際上,OOP 的這些「原則」是什麼?讓我們更詳細地告訴你。
物件導向原則
這是基礎知識。4 個主要特徵共同構成了物件導向程式設計範式。理解它們是成為成功程式設計師的關鍵。原則1.繼承
好消息是您已經熟悉 OOP 的一些原則!:) 我們已經在講座中遇到過幾次繼承,我們有時間使用它。 繼承是一種允許您基於現有(父)類別描述新類別的機制。在這種情況下,新類別借用了父類別的屬性和功能。為什麼繼承是必要的以及它能帶來什麼好處?首先,程式碼重用。父類別中描述的字段和方法可以在後代類別中使用。如果所有類型的汽車都有10個公共欄位和5個相同的方法,則只需將它們放在父類別中即可Auto
。您可以在後代類別中使用它們,沒有任何問題。堅實的優勢:定量(更少的程式碼)和定性(類別變得更簡單)。同時,繼承機制非常靈活,您可以在後代中單獨添加缺少的功能(特定於特定類別的某些欄位或行為)。一般來說,就像在日常生活中一樣:我們在某些方面與我們的父母相似,但在某些方面又與他們不同:)
原則 2. 抽象
這是一個非常簡單的原則。抽象意味著突顯物件的主要、最重要的特徵,反之亦然──丟棄次要的、無關緊要的特徵。讓我們不要重新發明輪子,記住一個關於類別的舊講座中的例子。假設我們正在建立一個公司員工的文件櫃。為了創建員工對象,我們編寫了一個類別Employee
。哪些特徵對於公司文件中的描述很重要?全名、出生日期、社會安全號碼、納稅識別號碼。但在這種類型的卡片中,我們不太可能需要他的身高、眼睛和頭髮顏色。公司不需要有關員工的這些資訊。因此,對於該類,Employee
我們將設定變數String name
、int age
、int socialInsuranceNumber
和int taxNumber
,我們將放棄對我們來說不必要的訊息,例如眼睛顏色,並將其抽象化。但如果我們為一家代理商創建照片模特兒目錄,情況就會發生巨大變化。為了描述一個時裝模特,身高、眼睛顏色和頭髮顏色對我們來說非常重要,但不需要 TIN 號碼。因此,在類別中Model
我們創建變數String height
, String hair
, String eyes
。
原則 3:封裝
我們已經遇到過。Java 中的封裝意味著限制對資料的存取和更改資料的能力。正如你所看到的,它是基於“膠囊”這個詞。在這個「膠囊」中,我們隱藏了一些我們不希望任何人更改的重要數據。生活中的一個簡單例子。您有名字和姓氏。你認識的每個人都認識他們。但他們無權更改您的名字和姓氏。有人可能會說,這個過程被「封裝」在護照辦公室:你只能在那裡更改你的名字和姓氏,而且只有你自己可以這樣做。其他「使用者」對您的名字和姓氏具有唯讀存取權:) 另一個例子是您公寓中的錢。把它們放在房間中央顯眼的地方並不是一個好主意。任何「用戶」(來到您家的人)都可以更改您的錢數,即 接他們。最好將它們封裝在保險箱中。只有您才能訪問,並且只能使用特殊代碼。您已經使用過的封裝的明顯範例是存取修飾符(private
等public
)和 getter-setter。如果age
類別欄位Cat
沒有被封裝,任何人都可以寫:
Cat.age = -1000;
封裝機制允許我們使用age
setter 方法來保護字段,在該方法中我們可以檢查年齡不能為負數。
原理 4. 多態性
多態性是指將多種類型視為相同類型的能力。在這種情況下,物件的行為將根據它們所屬的類型而有所不同。聽起來有點複雜?現在我們就來弄清楚吧。讓我們舉一個最簡單的例子──動物。讓我們建立一個Animal
具有單一方法 -voice()
及其兩個子方法 -Cat
和的類別Dog
。
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Bow-wow!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
現在讓我們嘗試建立一個連結Animal
並為其分配一個物件Dog
。
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.voice();
}
}
您認為會呼叫哪個方法?Animal.voice()
或者Dog.voice()
?類別方法將被呼叫Dog
:Woof-woof!我們創建了一個引用Animal
,但該物件的行為類似於Dog
. 如果有必要,他可以表現得像貓、馬或其他動物。主要是將通用類型的參考分配Animal
給特定後代類別的物件。這是合乎邏輯的,因為所有的狗都是動物。這就是我們所說的「物件的行為會根據它們的類型而有所不同」。如果我們要建立一個物件Cat
-
public static void main(String[] args) {
Animal cat = new Cat();
cat.voice();
}
該方法voice()
將輸出“喵!” 「能夠像處理相同類型一樣處理多種類型」是什麼意思?這也很容易。讓我們想像一下,我們正在為動物創建一個美髮沙龍。我們的美髮沙龍必須能夠切割所有動物,因此我們將創建一個shear()
帶有參數的方法(“切割”)Animal
——我們要切割的動物。
public class AnimalBarbershop {
public void shear(Animal animal) {
System.out.println("The haircut is ready!");
}
}
現在我們可以將shear
物件Cat
和物件傳遞給方法Dog
!
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
AnimalBarbershop barbershop = new AnimalBarbershop();
barbershop.shear(cat);
barbershop.shear(dog);
}
這是一個明顯的例子:該類別AnimalBarbershop
使用類型,就好像它們是相同的類型Cat
一樣。Dog
同時,他們的行為Cat
也不同Dog
:他們以不同的方式使用自己的聲音。
GO TO FULL VERSION