更新時(shí)間:2021-08-25 10:49:51 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1419次
面向?qū)ο缶幊?(OOP) 是一種依賴于類和對(duì)象概念的編程范式。它用于將軟件程序構(gòu)建為簡(jiǎn)單、可重用的代碼藍(lán)圖(通常稱為類),用于創(chuàng)建對(duì)象的單個(gè)實(shí)例。有許多面向?qū)ο蟮木幊陶Z言,包括 JavaScript、C++、Java和Python。
一類是用于創(chuàng)建更具體的,具體對(duì)象的抽象藍(lán)圖。類通常代表廣泛的類別,例如Car或Dog共享屬性。這些類定義了此類型的實(shí)例將具有哪些屬性,例如color,但不定義特定對(duì)象的這些屬性的值。
類還可以包含函數(shù),稱為僅對(duì)該類型的對(duì)象可用的方法。這些函數(shù)在類中定義,并執(zhí)行一些對(duì)特定類型對(duì)象有幫助的操作。
例如,我們的Car類可能有一個(gè)方法repaint來改變color我們汽車的屬性。這個(gè)函數(shù)只對(duì) type 的對(duì)象有用Car,所以我們?cè)贑ar類中聲明它,從而使它成為一個(gè)方法。
類模板用作創(chuàng)建單個(gè)對(duì)象的藍(lán)圖。這些代表抽象類的特定示例,例如myCar或goldenRetriever。對(duì)于類中定義的屬性,每個(gè)對(duì)象都可以具有唯一值。
例如,假設(shè)我們創(chuàng)建一個(gè)類,Car以包含所有汽車必須具備的特性color,brand和model。然后我們創(chuàng)建一個(gè)Car類型對(duì)象的實(shí)例,myCar來代表我的特定汽車。
然后我們可以設(shè)置類中定義的屬性值來描述我的汽車,而不會(huì)影響其他對(duì)象或類模板。
然后我們可以重用這個(gè)類來表示任意數(shù)量的汽車。

OOP 將復(fù)雜事物建模為可重現(xiàn)的簡(jiǎn)單結(jié)構(gòu)
可重用,OOP 對(duì)象可以跨程序使用
允許通過多態(tài)實(shí)現(xiàn)特定于類的行為
更容易調(diào)試,類通常包含所有適用的信息
安全,通過封裝保護(hù)信息
讓我們考慮一個(gè)現(xiàn)實(shí)世界的問題,從概念上設(shè)計(jì)一個(gè) OOP 軟件程序。
想象一下,經(jīng)營(yíng)一個(gè)有數(shù)百只寵物的狗訓(xùn)練營(yíng),您必須跟蹤每只寵物的姓名、年齡和參加日期。您將如何設(shè)計(jì)簡(jiǎn)單、可重復(fù)使用的軟件來為狗建模?
有數(shù)百只狗,為每只狗編寫唯一代碼將是低效的。下面我們將看到對(duì)象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
}
正如你在上面看到的,兩個(gè)對(duì)象之間有很多重復(fù)的代碼。該age()函數(shù)出現(xiàn)在每個(gè)對(duì)象中。由于我們希望每只狗都有相同的信息,因此我們可以使用對(duì)象和類來代替。
將相關(guān)信息組合在一起形成類結(jié)構(gòu)使代碼更短且更易于維護(hù)。
在養(yǎng)狗示例中,以下是程序員如何考慮組織 OOP:
為所有狗創(chuàng)建一個(gè)父類,作為所有狗都將擁有的信息和行為(方法)的藍(lán)圖,無論類型如何。
在通用父藍(lán)圖下創(chuàng)建子類來表示狗的不同子類別。
向子類添加獨(dú)特的屬性和行為以表示差異
從代表該子組中的狗的子類創(chuàng)建對(duì)象
下圖展示了如何設(shè)計(jì) OOP 程序:將相關(guān)數(shù)據(jù)和行為組合在一起形成一個(gè)簡(jiǎn)單的模板,然后為專門的數(shù)據(jù)和行為創(chuàng)建子組。
該Dog班是一個(gè)通用模板,只包含有關(guān)數(shù)據(jù),并適用于所有的狗行為的結(jié)構(gòu)。
然后我們創(chuàng)建兩個(gè)子類Dog,HerdingDog和TrackingDog。它們具有Dog( bark())的遺傳行為,但也具有該亞型狗獨(dú)有的行為。
最后,我們創(chuàng)建該HerdingDog類型的對(duì)象來表示單個(gè)狗Fluffy和Maisel。
我們還可以創(chuàng)建這樣的對(duì)象Rufus,該對(duì)象適合廣泛的類 ,Dog但不適合HerdingDog或TrackingDog。

接下來,我們將深入了解上面使用的 OOP 程序的每個(gè)基本構(gòu)建塊:
班級(jí)
對(duì)象
方法
屬性
班級(jí)
簡(jiǎn)而言之,類本質(zhì)上是用戶定義的數(shù)據(jù)類型。類是我們?yōu)榉椒ê蛯傩缘慕Y(jié)構(gòu)創(chuàng)建藍(lán)圖的地方。單個(gè)對(duì)象是從該藍(lán)圖實(shí)例化或創(chuàng)建的。
類包含屬性字段和行為方法。在我們的Dog類示例中,屬性包括name& birthday,而方法包括bark()和updateAttendance()。
下面的代碼片段演示了如何Dog使用JavaScript語言對(duì)類進(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++;
}
}
請(qǐng)記住,該類是用于建模狗的模板,并且對(duì)象是從代表單個(gè)現(xiàn)實(shí)世界事物的類實(shí)例化的。
對(duì)象
當(dāng)然 OOP 包括對(duì)象!對(duì)象是使用特定數(shù)據(jù)創(chuàng)建的類的實(shí)例,例如在下面的代碼片段中Rufus是Dog類的實(shí)例。
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)用時(shí):
創(chuàng)建了一個(gè)名為的新對(duì)象 rufus
構(gòu)造函數(shù)運(yùn)行name&birthday參數(shù),并分配值
屬性
屬性是存儲(chǔ)的信息。屬性在Class模板中定義。當(dāng)對(duì)象被實(shí)例化時(shí),單個(gè)對(duì)象包含存儲(chǔ)在 Attributes 字段中的數(shù)據(jù)。
對(duì)象的狀態(tài)由對(duì)象屬性字段中的數(shù)據(jù)定義。例如,在寵物營(yíng)地,一只小狗和一只狗可能受到不同的對(duì)待。生日可以定義對(duì)象的狀態(tài),并允許軟件以不同的方式處理不同年齡的狗。
方法
方法代表行為。方法執(zhí)行動(dòng)作;方法可能會(huì)返回有關(guān)對(duì)象的信息,或更新對(duì)象的數(shù)據(jù)。方法的代碼在類定義中定義。
當(dāng)單個(gè)對(duì)象被實(shí)例化時(shí),這些對(duì)象可以調(diào)用類中定義的方法。在下面的代碼片段中,bark方法是在Dog類中定義的,bark()方法是在Rufus對(duì)象上調(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()方法不會(huì)更新任何數(shù)據(jù),因?yàn)?barking 不會(huì)修改類的任何屬性Dog:name或birthday。
該updateAttendance()方法增加了Dog參加寵物訓(xùn)練營(yíng)的一天。出勤屬性對(duì)于在月底跟蹤計(jì)費(fèi)所有者很重要。
方法是程序員促進(jìn)可重用性并將功能封裝在對(duì)象中的方式。這種可重用性在調(diào)試時(shí)是一個(gè)很大的好處。如果出現(xiàn)錯(cuò)誤,只有一個(gè)地方可以找到并修復(fù)它,而不是很多地方。
下劃線 in_attendance表示該變量是受保護(hù)的,不應(yīng)直接修改。該updateAttendance()方法用于更改_attendance.
面向?qū)ο缶幊痰乃拇笾е牵?/p>
繼承:子類繼承父類的數(shù)據(jù)和行為
封裝:在對(duì)象中包含信息,只暴露選定的信息
抽象:只公開訪問對(duì)象的高級(jí)公共方法
多態(tài)性:許多方法可以完成相同的任務(wù)
遺產(chǎn)
繼承允許類繼承其他類的特性。換句話說,父類將屬性和行為擴(kuò)展到子類。繼承支持可重用性。
如果在父類中定義了基本屬性和行為,則可以創(chuàng)建子類來擴(kuò)展父類的功能,并添加額外的屬性和行為。
例如,牧羊犬具有獨(dú)特的放牧能力。換句話說,所有的牧羊犬都是狗,但并非所有的狗都是牧羊犬。我們通過HerdingDog從父類創(chuàng)建一個(gè)子類來表示這種差異Dog,然后添加獨(dú)特的herd()行為。
繼承的好處是程序可以創(chuàng)建一個(gè)通用的父類,然后根據(jù)需要?jiǎng)?chuàng)建更具體的子類。這簡(jiǎn)化了整體編程,因?yàn)樽宇悷o需Dog多次重新創(chuàng)建類的結(jié)構(gòu),而是自動(dòng)獲得對(duì)其父類中功能的訪問權(quán)限。
在下面的代碼片段中,子類HerdingDog繼承了bark父類Dog的方法,子類添加了一個(gè)額外的方法,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!")
}
}
請(qǐng)注意,HerdingDog該類沒有bark()方法的副本,它繼承bark()了父Dog類中定義的方法。
當(dāng)代碼調(diào)用fluffy.bark()方法時(shí),該bark()方法會(huì)沿著子類到父類的鏈向上走,以找到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è)計(jì)。原型對(duì)象充當(dāng)另一個(gè)對(duì)象從中繼承屬性和行為的模板。可以有多個(gè)原型對(duì)象模板,創(chuàng)建一個(gè)原型鏈。
這與父/子繼承的概念相同。繼承是從父到子的。在我們的示例中,所有三只狗都可以吠叫,但只有 Maisel 和 Fluffy 可以放牧。
該herd()方法在子HerdingDog類中定義,因此從該類實(shí)例化的兩個(gè)對(duì)象Maisel和可以訪問該方法。FluffyHerdingDogherd()
Rufus 是從父類實(shí)例化的對(duì)象Dog,因此 Rufus 只能訪問該bark()方法。
封裝
封裝意味著將所有重要信息包含在一個(gè)對(duì)象內(nèi)部,并且只將選定的信息暴露給外部世界。屬性和行為由類模板內(nèi)的代碼定義。
然后,當(dāng)從類中實(shí)例化對(duì)象時(shí),數(shù)據(jù)和方法被封裝在該對(duì)象中。封裝將內(nèi)部的軟件代碼實(shí)現(xiàn)隱藏在一個(gè)類中,隱藏了內(nèi)部對(duì)象的內(nèi)部數(shù)據(jù)。
封裝需要將某些字段定義為私有字段,將某些字段定義為公共字段。
私有/內(nèi)部接口:方法和屬性,可從同一類的其他方法訪問。
公共/外部接口:方法和屬性,也可以從類外部訪問。
抽象
抽象意味著用戶僅與對(duì)象的選定屬性和方法進(jìn)行交互。抽象使用簡(jiǎn)化的高級(jí)工具來訪問復(fù)雜的對(duì)象。
用簡(jiǎn)單的事物來表示復(fù)雜性
對(duì)用戶隱藏復(fù)雜的細(xì)節(jié)
抽象是使用簡(jiǎn)單的類來表示復(fù)雜性。抽象是封裝的擴(kuò)展。例如,您不必了解發(fā)動(dòng)機(jī)如何工作來驅(qū)動(dòng)汽車的所有細(xì)節(jié)。
駕駛員只使用一小部分工具:如油門踏板、剎車、方向盤、閃光燈。工程對(duì)司機(jī)是隱藏的。為了讓汽車運(yùn)轉(zhuǎn)起來,很多部件都必須在引擎蓋下工作,但是將這些信息暴露給駕駛員會(huì)很危險(xiǎn)地分散注意力。
抽象也起著重要的安全作用。通過只顯示選定的數(shù)據(jù)片段,并且只允許通過類訪問數(shù)據(jù)和通過方法修改數(shù)據(jù),我們可以保護(hù)數(shù)據(jù)不被暴露。繼續(xù)以汽車為例,您不希望在駕駛汽車時(shí)打開油箱。
抽象的好處總結(jié)如下:
簡(jiǎn)單、高級(jí)的用戶界面
復(fù)雜代碼被隱藏
安全
更輕松的軟件維護(hù)
代碼更新很少改變抽象
多態(tài)性
多態(tài)意味著設(shè)計(jì)對(duì)象來共享行為。使用繼承,對(duì)象可以覆蓋共享的父行為,具有特定的子行為。多態(tài)允許同一個(gè)方法以兩種方式執(zhí)行不同的行為:方法覆蓋和方法重載。
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"面向?qū)ο缶幊蹋篛OP深入解釋",希望對(duì)大家有幫助,想了解更多可查看Java教程。動(dòng)力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對(duì)沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識(shí),讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)