更新時間:2021-08-25 10:49:51 來源:動力節(jié)點 瀏覽1189次
面向?qū)ο缶幊?(OOP) 是一種依賴于類和對象概念的編程范式。它用于將軟件程序構(gòu)建為簡單、可重用的代碼藍(lán)圖(通常稱為類),用于創(chuàng)建對象的單個實例。有許多面向?qū)ο蟮木幊陶Z言,包括 JavaScript、C++、Java和Python。
一類是用于創(chuàng)建更具體的,具體對象的抽象藍(lán)圖。類通常代表廣泛的類別,例如Car或Dog共享屬性。這些類定義了此類型的實例將具有哪些屬性,例如color,但不定義特定對象的這些屬性的值。
類還可以包含函數(shù),稱為僅對該類型的對象可用的方法。這些函數(shù)在類中定義,并執(zhí)行一些對特定類型對象有幫助的操作。
例如,我們的Car類可能有一個方法repaint來改變color我們汽車的屬性。這個函數(shù)只對 type 的對象有用Car,所以我們在Car類中聲明它,從而使它成為一個方法。
類模板用作創(chuàng)建單個對象的藍(lán)圖。這些代表抽象類的特定示例,例如myCar或goldenRetriever。對于類中定義的屬性,每個對象都可以具有唯一值。
例如,假設(shè)我們創(chuàng)建一個類,Car以包含所有汽車必須具備的特性color,brand和model。然后我們創(chuàng)建一個Car類型對象的實例,myCar來代表我的特定汽車。
然后我們可以設(shè)置類中定義的屬性值來描述我的汽車,而不會影響其他對象或類模板。
然后我們可以重用這個類來表示任意數(shù)量的汽車。
OOP 將復(fù)雜事物建模為可重現(xiàn)的簡單結(jié)構(gòu)
可重用,OOP 對象可以跨程序使用
允許通過多態(tài)實現(xiàn)特定于類的行為
更容易調(diào)試,類通常包含所有適用的信息
安全,通過封裝保護(hù)信息
讓我們考慮一個現(xiàn)實世界的問題,從概念上設(shè)計一個 OOP 軟件程序。
想象一下,經(jīng)營一個有數(shù)百只寵物的狗訓(xùn)練營,您必須跟蹤每只寵物的姓名、年齡和參加日期。您將如何設(shè)計簡單、可重復(fù)使用的軟件來為狗建模?
有數(shù)百只狗,為每只狗編寫唯一代碼將是低效的。下面我們將看到對象rufus和fluffy.
//Object of one individual dog
var rufus = {
name: "Rufus",
birthday: "2/1/2017",
age: function() {
return Date.now() - this.birthday;
},
attendance: 0
}
//Object of second individual dog
var fluffy = {
name: "Fluffy",
birthday: "1/12/2019",
age: function() {
return Date.now() - this.birthday;
},
attendance: 0
}
正如你在上面看到的,兩個對象之間有很多重復(fù)的代碼。該age()函數(shù)出現(xiàn)在每個對象中。由于我們希望每只狗都有相同的信息,因此我們可以使用對象和類來代替。
將相關(guān)信息組合在一起形成類結(jié)構(gòu)使代碼更短且更易于維護(hù)。
在養(yǎng)狗示例中,以下是程序員如何考慮組織 OOP:
為所有狗創(chuàng)建一個父類,作為所有狗都將擁有的信息和行為(方法)的藍(lán)圖,無論類型如何。
在通用父藍(lán)圖下創(chuàng)建子類來表示狗的不同子類別。
向子類添加獨特的屬性和行為以表示差異
從代表該子組中的狗的子類創(chuàng)建對象
下圖展示了如何設(shè)計 OOP 程序:將相關(guān)數(shù)據(jù)和行為組合在一起形成一個簡單的模板,然后為專門的數(shù)據(jù)和行為創(chuàng)建子組。
該Dog班是一個通用模板,只包含有關(guān)數(shù)據(jù),并適用于所有的狗行為的結(jié)構(gòu)。
然后我們創(chuàng)建兩個子類Dog,HerdingDog和TrackingDog。它們具有Dog( bark())的遺傳行為,但也具有該亞型狗獨有的行為。
最后,我們創(chuàng)建該HerdingDog類型的對象來表示單個狗Fluffy和Maisel。
我們還可以創(chuàng)建這樣的對象Rufus,該對象適合廣泛的類 ,Dog但不適合HerdingDog或TrackingDog。
接下來,我們將深入了解上面使用的 OOP 程序的每個基本構(gòu)建塊:
班級
對象
方法
屬性
班級
簡而言之,類本質(zhì)上是用戶定義的數(shù)據(jù)類型。類是我們?yōu)榉椒ê蛯傩缘慕Y(jié)構(gòu)創(chuàng)建藍(lán)圖的地方。單個對象是從該藍(lán)圖實例化或創(chuàng)建的。
類包含屬性字段和行為方法。在我們的Dog類示例中,屬性包括name& birthday,而方法包括bark()和updateAttendance()。
下面的代碼片段演示了如何Dog使用JavaScript語言對類進(jìn)行編程。
class Dog {
constructor(name, birthday) {
this.name = name;
this.birthday = birthday;
}
//Declare private variables
_attendance = 0;
getAge() {
//Getter
return this.calcAge();
}
calcAge() {
//calculate age using today's date and birthday
return Date.now() - this.birthday;
}
bark() {
return console.log("Woof!");
}
updateAttendance() {
//add a day to the dog's attendance days at the petsitters
this._attendance++;
}
}
請記住,該類是用于建模狗的模板,并且對象是從代表單個現(xiàn)實世界事物的類實例化的。
對象
當(dāng)然 OOP 包括對象!對象是使用特定數(shù)據(jù)創(chuàng)建的類的實例,例如在下面的代碼片段中Rufus是Dog類的實例。
class Dog {
constructor(name, birthday) {
this.name = name;
this.birthday = birthday;
}
//Declare private variables
_attendance = 0;
getAge() {
//Getter
return this.calcAge();
}
calcAge() {
//calculate age using today's date and birthday
return Date.now() - this.birthday;
}
bark() {
return console.log("Woof!");
}
updateAttendance() {
//add a day to the dog's attendance days at the petsitters
this._attendance++;
}
}
//instantiate a new object of the Dog class, and individual dog named Rufus
const rufus = new Dog("Rufus", "2/1/2017");
當(dāng)新類Dog被調(diào)用時:
創(chuàng)建了一個名為的新對象 rufus
構(gòu)造函數(shù)運行name&birthday參數(shù),并分配值
屬性
屬性是存儲的信息。屬性在Class模板中定義。當(dāng)對象被實例化時,單個對象包含存儲在 Attributes 字段中的數(shù)據(jù)。
對象的狀態(tài)由對象屬性字段中的數(shù)據(jù)定義。例如,在寵物營地,一只小狗和一只狗可能受到不同的對待。生日可以定義對象的狀態(tài),并允許軟件以不同的方式處理不同年齡的狗。
方法
方法代表行為。方法執(zhí)行動作;方法可能會返回有關(guān)對象的信息,或更新對象的數(shù)據(jù)。方法的代碼在類定義中定義。
當(dāng)單個對象被實例化時,這些對象可以調(diào)用類中定義的方法。在下面的代碼片段中,bark方法是在Dog類中定義的,bark()方法是在Rufus對象上調(diào)用的。
class Dog {
//Declare protected (private) fields
_attendance = 0;
constructor(name, birthday) {
this.namee = name;
this.birthday = birthday;
}
getAge() {
//Getter
return this.calcAge();
}
calcAge() {
//calculate age using today's date and birthday
return this.calcAge();
}
bark() {
return console.log("Woof!");
}
updateAttendance() {
//add a day to the dog's attendance days at the petsitters
this._attendance++;
}
}
方法經(jīng)常修改、更新或刪除數(shù)據(jù)。方法不必更新數(shù)據(jù)。例如,該bark()方法不會更新任何數(shù)據(jù),因為 barking 不會修改類的任何屬性Dog:name或birthday。
該updateAttendance()方法增加了Dog參加寵物訓(xùn)練營的一天。出勤屬性對于在月底跟蹤計費所有者很重要。
方法是程序員促進(jìn)可重用性并將功能封裝在對象中的方式。這種可重用性在調(diào)試時是一個很大的好處。如果出現(xiàn)錯誤,只有一個地方可以找到并修復(fù)它,而不是很多地方。
下劃線 in_attendance表示該變量是受保護(hù)的,不應(yīng)直接修改。該updateAttendance()方法用于更改_attendance.
面向?qū)ο缶幊痰乃拇笾е牵?/p>
繼承:子類繼承父類的數(shù)據(jù)和行為
封裝:在對象中包含信息,只暴露選定的信息
抽象:只公開訪問對象的高級公共方法
多態(tài)性:許多方法可以完成相同的任務(wù)
遺產(chǎn)
繼承允許類繼承其他類的特性。換句話說,父類將屬性和行為擴(kuò)展到子類。繼承支持可重用性。
如果在父類中定義了基本屬性和行為,則可以創(chuàng)建子類來擴(kuò)展父類的功能,并添加額外的屬性和行為。
例如,牧羊犬具有獨特的放牧能力。換句話說,所有的牧羊犬都是狗,但并非所有的狗都是牧羊犬。我們通過HerdingDog從父類創(chuàng)建一個子類來表示這種差異Dog,然后添加獨特的herd()行為。
繼承的好處是程序可以創(chuàng)建一個通用的父類,然后根據(jù)需要創(chuàng)建更具體的子類。這簡化了整體編程,因為子類無需Dog多次重新創(chuàng)建類的結(jié)構(gòu),而是自動獲得對其父類中功能的訪問權(quán)限。
在下面的代碼片段中,子類HerdingDog繼承了bark父類Dog的方法,子類添加了一個額外的方法,herd()。
//Parent class Dog
class Dog{
//Declare protected (private) fields
_attendance = 0;
constructor(namee, birthday) {
this.name = name;
this.birthday = birthday;
}
getAge() {
//Getter
return this.calcAge();
}
calcAge() {
//calculate age using today's date and birthday
return this.calcAge();
}
bark() {
return console.log("Woof!");
}
updateAttendance() {
//add a day to the dog's attendance days at the petsitters
this._attendance++;
}
}
//Child class HerdingDog, inherits from parent Dog
class HerdingDog extends Dog {
constructor(name, birthday) {
super(name);
super(birthday);
}
herd() {
//additional method for HerdingDog child class
return console.log("Stay together!")
}
}
請注意,HerdingDog該類沒有bark()方法的副本,它繼承bark()了父Dog類中定義的方法。
當(dāng)代碼調(diào)用fluffy.bark()方法時,該bark()方法會沿著子類到父類的鏈向上走,以找到bark定義方法的位置。
//Parent class Dog
class Dog{
//Declare protected (private) fields
_attendance = 0;
constructor(namee, birthday) {
this.name = name;
this.birthday = birthday;
}
getAge() {
//Getter
return this.calcAge();
}
calcAge() {
//calculate age using today's date and birthday
return this.calcAge();
}
bark() {
return console.log("Woof!");
}
updateAttendance() {
//add a day to the dog's attendance days at the petsitters
this._attendance++;
}
}
//Child class HerdingDog, inherits from parent Dog
class HerdingDog extends Dog {
constructor(name, birthday) {
super(name);
super(birthday);
}
herd() {
//additional method for HerdingDog child class
return console.log("Stay together!")
}
}
//instantiate a new HerdingDog object
const fluffy = new HerdingDog("Fluffy", "1/12/2019");
fluffy.bark();
在 JavaScript 中,繼承也稱為原型設(shè)計。原型對象充當(dāng)另一個對象從中繼承屬性和行為的模板。可以有多個原型對象模板,創(chuàng)建一個原型鏈。
這與父/子繼承的概念相同。繼承是從父到子的。在我們的示例中,所有三只狗都可以吠叫,但只有 Maisel 和 Fluffy 可以放牧。
該herd()方法在子HerdingDog類中定義,因此從該類實例化的兩個對象Maisel和可以訪問該方法。FluffyHerdingDogherd()
Rufus 是從父類實例化的對象Dog,因此 Rufus 只能訪問該bark()方法。
封裝
封裝意味著將所有重要信息包含在一個對象內(nèi)部,并且只將選定的信息暴露給外部世界。屬性和行為由類模板內(nèi)的代碼定義。
然后,當(dāng)從類中實例化對象時,數(shù)據(jù)和方法被封裝在該對象中。封裝將內(nèi)部的軟件代碼實現(xiàn)隱藏在一個類中,隱藏了內(nèi)部對象的內(nèi)部數(shù)據(jù)。
封裝需要將某些字段定義為私有字段,將某些字段定義為公共字段。
私有/內(nèi)部接口:方法和屬性,可從同一類的其他方法訪問。
公共/外部接口:方法和屬性,也可以從類外部訪問。
抽象
抽象意味著用戶僅與對象的選定屬性和方法進(jìn)行交互。抽象使用簡化的高級工具來訪問復(fù)雜的對象。
用簡單的事物來表示復(fù)雜性
對用戶隱藏復(fù)雜的細(xì)節(jié)
抽象是使用簡單的類來表示復(fù)雜性。抽象是封裝的擴(kuò)展。例如,您不必了解發(fā)動機(jī)如何工作來驅(qū)動汽車的所有細(xì)節(jié)。
駕駛員只使用一小部分工具:如油門踏板、剎車、方向盤、閃光燈。工程對司機(jī)是隱藏的。為了讓汽車運轉(zhuǎn)起來,很多部件都必須在引擎蓋下工作,但是將這些信息暴露給駕駛員會很危險地分散注意力。
抽象也起著重要的安全作用。通過只顯示選定的數(shù)據(jù)片段,并且只允許通過類訪問數(shù)據(jù)和通過方法修改數(shù)據(jù),我們可以保護(hù)數(shù)據(jù)不被暴露。繼續(xù)以汽車為例,您不希望在駕駛汽車時打開油箱。
抽象的好處總結(jié)如下:
簡單、高級的用戶界面
復(fù)雜代碼被隱藏
安全
更輕松的軟件維護(hù)
代碼更新很少改變抽象
多態(tài)性
多態(tài)意味著設(shè)計對象來共享行為。使用繼承,對象可以覆蓋共享的父行為,具有特定的子行為。多態(tài)允許同一個方法以兩種方式執(zhí)行不同的行為:方法覆蓋和方法重載。
以上就是動力節(jié)點小編介紹的"面向?qū)ο缶幊蹋篛OP深入解釋",希望對大家有幫助,想了解更多可查看Java教程。動力節(jié)點在線學(xué)習(xí)教程,針對沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識,讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
初級 202925
初級 203221
初級 202629
初級 203743