摘要:面向對象三大特性就是封裝繼承和多態,簡單理解,對于貓這種動物,它本身就是一個封裝好的類,你只需要供它吃喝輸入,它就能表現貓的行為輸出,同時它繼承了動物所具有的習性吃東西等,而不同的貓因為所處環境或者習性的不同,可能會有不同的表現和行為,這就
面向對象三大特性就是封裝繼承和多態,簡單理解,對于貓這種動物,它本身就是一個封裝好的類,你只需要供它吃喝(輸入),它就能表現貓的行為(輸出),同時它繼承了動物所具有的習性(吃東西等~),而不同的貓因為所處環境或者習性的不同,可能會有不同的表現和行為,這就是多態。
封裝
把客觀事物封裝成抽象的類,隱藏屬性和方法的實現細節,僅對外公開接口。
① 在ES6之前,沒有class這個概念,借由原型對象和構造函數來實現
function Cat(name, food) { this.name = name // 公有屬性 this.food = food } Cat.prototype.say = function() { // 公有方法 console.log(this.name + " likes eating " + this.food) } Cat.see = function() { console.log("這是靜態方法,無需實例化可調用") } var cat = new Cat("Lazier","mouse") cat.say() // 實例共享原型屬性和方法
② ES6的class
class Cat{ constructor(name, food){ this.name = name this.food = food } static see() { console.log("這是靜態方法,無需實例化可調用") } say(){ console.log(this.name+" likes eating " + this.food) } } var cat = new Cat("Lazier","mouse") cat.say()
以上class的基本實現原理如下 ↓
var Cat = function(){ function Cat(name, food){ this.name = name this.food = food } // 執行掛載函數,創建類 createClass(Cat,[{key:"say",value:function(){ console.log(this.name+" likes eating " + this.food) }}],[{key:"see",value:function(){ console.log("這是靜態方法,無需實例化可調用")}]) } // 定義對象屬性 let defineProperties = function(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i] Object.defineProperty(target, descriptor.key, descriptor) } } // 掛載函數,將靜態或動態方法分別掛載到Cat和Cat的prototype上 var createClass = function({ return function(Constructor,protoProps,staticProps){ if(protoProps){ // 原型方法 defineProperties(Constructor.prototype,protoProps) } if(staticProps){ // 靜態方法 defineProperties(Constructor,staticProps) } } })
了解面向對象的公有、私有、靜態屬性和方法可以看下面這篇文章的總結
js面向對象之公有、私有、靜態屬性和方法詳解
繼承
子類可以使用父類的所有功能,并且對這些功能進行擴展。繼承的過程,就是從一般到特殊的過程。
js實現繼承有多種方式
原型鏈繼承
// 將子類的prototype指向父類的實例 function Parent(){} function Son(){} Son.prototype = new Parent() // * 把Son的原型對象的constructor指向Son,解決類型判斷問題 Son.prototype.constructor = Son 借助構造函數繼承(使用call和apply實現繼承) function Parent(){} function Son(){ // 將父類函數中的this,強行綁定為子類的this // 可傳參 Parent.call(this, arguments); } 組合繼承 // 原型屬性方法由原型鏈實現繼承,實例屬性方法由借用構造函數實現繼承 // 這樣,在原型上定義方法實現了函數復用,又保證每個實例都有它自己的屬性 function Parent(name){ this.name = name } function Son(name, age){ // 繼承父類的實例屬性方法,之后再添加自己的實例屬性方法 Parent.call(this, name); this.age = age } Son.prototype = new Parent() // 重寫Son的原型對象 Son.prototype.constructor = Son var demo = new Son("jacksonzhou", 23) 寄生式組合繼承 – 現在最常用的繼承方法 // 獲得父類原型屬性方法的副本,解決組合繼承的屬性重復問題 function inheritPrototype(son, parent) { var prototype = object(parent.prototype) prototype.constructor = son son.prototype = prototype } function Parent(name){ this.name = name } function Son(name, age){ Parent.call(this, name) this.age = age } Son.prototype = inheritPrototype(Son, Parent) var demo = new Son("jacksonzhou", 23)
多態
同一操作用在不同對象上,可以產生不同的解釋和不同的執行結果
var makeSound=function(animal){ animal.sound() } // 聲明狗的構造函數 var Dog=function(){} Dog.prototype.sound=function(){ console.log("汪汪汪") } // 聲明貓的構造函數 var Cat=function(){} Cat.prototype.sound=function(){ console.log("喵喵喵") } // 分別調用他們的叫法 makeSound(new Dog()) makeSound(new Cat()) // 非多態寫法 var makeSound=function(animal){ if(animal instanceof Dog){ console.log("汪汪汪") }else if(animal instanceof Cat){ console.log("喵喵喵") } } var Dog=function(){} var Cat=function(){} // 分別調用他們的叫法 makeSound(new Dog()) makeSound(new Cat()) // 很明顯,后續有其他動物加入都要去修改makeSound函數,很不優雅! 這里要介紹下方法重載 方法重載是讓類以統一的方式處理不同類型數據的一種手段。表現為多個同名函數同時存在,但具有不同的參數個數或類型。調用方法時通過傳遞給它們的不同參數個數和參數類型來決定具體使用哪個方法, 這也是一種多態性。 其實js本身并沒有這個概念,但我們可以通過操作參數的類數組arguments,根據該類數組的長度以及其元素的類型來選擇不同的實現,來模擬實現函數重載效果 // js的函數參數相當靈活~可理解成一個動態的類數組 // 不加參數,調用時有傳入參數也不會報錯 function countCat(){ if(arguments.length==1){ console.log(`這是一只貓,${arguments[0]}`) } else if(arguments.length==2){ console.log(`這是兩只貓,${arguments[0]}和${arguments[1]}`) } else{ console.log("沒貓了~") } } countCat() countCat("Tom") countCat("Tom","Mary")
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106883.html
摘要:我們都知道面向對象擁有三大特征,分別為封裝繼承多態,其實在腳本語言中是不存在多態的,但是可以用的方式實現多態中的兩種效果重載重寫,那下面我們就來說一下面向對象的特征封裝把抽象出的屬性和對屬性的方法封裝在一起對外實現接口開放,說白了就是封裝一 我們都知道js面向對象擁有三大特征,分別為封裝、繼承、多態,其實在javaScript腳本語言中是不存在多態的,但是可以用js的方式實現多態中的兩...
摘要:會造成內存浪費的問題構造函數繼承聲明父類聲明子類生成實例組合式繼承組合式繼承是汲取了兩者的優點,既避免了內存浪費,又使得每個實例化的子類互不影響。 寫在前面 既然是淺談,就不會從原理上深度分析,只是幫助我們更好地理解... 面向對象與面向過程 面向對象和面向過程是兩種不同的編程思想,剛開始接觸編程的時候,我們大都是從面向過程起步的,畢竟像我一樣,大家接觸的第一門計算機語言大概率都是C語...
摘要:為什么要學習設計模式做事情之前問個為什么總是好的。設計模式的使用方法關于使用方式,像我這種初學者最容易犯的錯誤就是生搬硬套,但是模仿本來也是學習的一個過程,最重要的事情是在模仿中要學會思考。 為什么要學習設計模式? 做事情之前問個為什么總是好的。關于設計模式的好壞,我在知乎上也看過一些討論,有知友對其提出過一些疑問,里面有一些關于設計模式的觀點: 設計模式有何不妥,所謂的荼毒體現在哪...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
閱讀 3529·2021-11-22 11:59
閱讀 945·2021-09-27 13:36
閱讀 3603·2021-09-24 09:47
閱讀 2251·2021-09-01 11:39
閱讀 970·2021-08-31 09:37
閱讀 2304·2021-08-05 10:01
閱讀 1665·2019-08-30 15:55
閱讀 695·2019-08-30 15:54