Web開發學習筆記16 — OOP(Object Oriented Programming)

文章推薦指數: 80 %
投票人數:10人

What Are JavaScript Constructor Functions? Day 10: ES6篇- Class(類別) · JavaScript | ES6 中最容易誤會的語法糖Class - 基本用法 · [教學] ... 老靈魂手冊 Menu Home About Series Tags Archives RSS SignIn ObjectOrientedProgramming(OOP)是什麼? OOP又被叫做物件導向程式設計,是一種程式設計法(Programmingparadigm)。

OOP與傳統程式設計:程序式程式設計(Proceduralprogramming)有著很大的不同,OOP將相關的變數(屬性)與函式(方法)結合成一個單位(也就是物件),這使得程式的複雜性降低、靈活性提高。

OOP的四大pillar(支柱) OOP總共有四大支柱,分別是: Encapsulation Abstraction Inheritance Polymorphism Encapsulation(封裝) Encapsulation這個概念是在說,我們可以把許多屬性、方法包裝成一個物件使用把OOP與Proceduralprogramming來比較就會像是這樣: //Proceduralprogramming變數與函式分開寫: letincome=50000 letexpense=30000 functionsaving(income,expense){ returnincome-expense } saving();//20000 //ObjectOrientedProgramming將變數與函式結合成一個物件 letperson={ income:50000, expense:30000, saving:function(){ return(this.income-this.expense) } } person.saving();//20000 Encapsulation的優點在於參數很少或沒有,降低了程式的複雜性與提供了靈活性。

Abstraction(抽象) Abstraction指得是將此物件的某些屬性與方法隱藏(hide)起來。

舉例來說,我們按下遙控器的按鈕就能轉台,其實這是靠遙控器內的小零件互相作用的,但我們不必知道這些。

這些被隱藏在遙控器裡的零件與作用就像是被隱藏起來的屬性與方法。

Abstraction的優點是①使物件的介面更簡單②減少改變的影響 Inheritance(繼承) Inheritance的概念就是繼承者擁有某些屬性或是方法,而這些是來自於被繼承者的,使繼承者透過Inheritance可以直接取用這些屬性與方法。

//arr1與arr2都繼承了Array.prototype的屬性與方法 //像是它們都可以使用map()、pop()、push()、reduce()這些方法 arr1=[1,2,3] arr2=[2,3,4] Polymorphism(多型) Polymorphism指的是使用相同名稱的方法,傳入不同的參數,會執行不同的指令。

假如我們要讓好多個物件渲染(render)頁面,在Proceduralprogramming就會長得像這樣,我們必須用好多switch和case: switch(...){ case'print':renderPrint(); case'text':renderText()} . . .} 但當我們用OOP的Polymorphism概念,就會變成這樣: element.rendar() 什麼是構造函式(ConstructorFunction)? 其實在筆記8有提到這個,構造函式也是函式的一種,只是它比較特別可以作為模板來創立其他物件們。

定義構造函式 我們可以使用new關鍵字呼叫構造函式,而透過this可以幫我們建立新物件。

此外,構造函式應該要是大寫字母開頭。

functionMovies(title,year){ this.title=title; this.year=year; } letmovie=newMovies('Joker',2019); movie;//Movies {title:"Joker",year:2019} movie.title;//"Joker" movie.year;//2019 什麼是Constructor與Class? 前面提到我們要構造一個新物件,它可能會長這樣: functionPCGame(name,genre){ this.name=name; this.genre=genre; this.score=null;}; pcGame.prototype.rate=function(score){ this.score=score; } letgame1=newPCGame('AgeofEmpires3','Real-timestrategy'); letgame2=newPCGame('TheOuterWorlds','Actionrole-playing'); 但當我們使用class與constructor改寫,它會長得像這樣: classPCGame{ constructor(name,genre,score){ this.name=name; this.genre=genre; this.socre=score; } rate(){ this.score=score } } letgame1=newPCGame('AgeofEmpires3','Real-timestrategy'); letgame2=newPCGame('TheOuterWorlds','Actionrole-playing'); class可以說是包裝好的prototype,讓語法看起來更清楚明瞭。

extends與super extends:用於創建一個類別(class),此類別是另一個類別的子類別,具有語法繼承 super:讀取或呼叫此類別的父類別的函數,注意super只能在constructor中執行,且super必須出現在this之前。

按照一般的構造函式寫法,例子會像這樣: functionPet(name,gender,age){ this.name=name; this.gender=gender; this.age=age; this.callPet=function(){ console.log(`This${this.name}is${this.age}yearsold,anditsgenderis${this.gender}`) } } functionCat(name,gender,age,breed){ Pet.call(this,name,gender,age); this.breed=breed; this.callCat=function(){ console.log(`This${this.name}isthe${this.breed}.It's${this.age}yearsold,anditsgenderis${this.gender}`) } } cat.callPet(); //Thiscatis3yearsold,anditsgenderisfemale cat.callCat(); //ThiscatistheAmericanShorthairCat.It's3yearsold,anditsgenderisfemale 想要讓Pet()裡的name也可以用到Cat()裡,就必須透過call(this.name)取得,但extends和super可以幫我們少掉這些麻煩!讓我們改寫一下程式: classPet{ constructor(name,gender,age){ this.name=name; this.gender=gender; this.age=age; } callPet(){ console.log(`This${this.name}is${this.age}yearsold,anditsgenderis${this.gender}`) } } classCatextendsPet{////用extends指定父類別 constructor(name,gender,age,breed){ super(name,gender,age);//用super呼叫父類別的函數 this.breed=breed; } callCat(){ console.log(`This${this.name}isthe${this.breed}.It's${this.age}yearsold,anditsgenderis${this.gender}`) } } letcat=newCat('cat','female',3,'AmericanShorthairCat') cat.callPet(); //Thiscatis3yearsold,anditsgenderisfemale cat.callCat(); //ThiscatistheAmericanShorthairCat.It's3yearsold,anditsgenderisfemale Static(靜態方法) static表示類別的靜態方法,被定義為靜態方法的函式可以直接以constructorfunction呼叫,它也無法被已實體化(new過)的類別物件呼叫。

//StaticMethod不需實體化所需類別的實例就可以被呼叫 classPerson{ constructor(name,age){ this.name=name; this.age=age; } staticstudent(name,age){ console.log(`I'm${name}.${age}yearsold.`)//不要加this } } Person.student('Teagan','22') //I'mTeagan.22yearsold. //被定義為靜態方法的函式,無法被已實體化(new過)的類別物件呼叫 letperson=newPerson('Teagan',22); person.student;//UncaughtTypeError:person.studentisnotafunction 按照一般寫法class寫法是: classPerson{ constructor(name,age){ this.name=name; this.age=age; } student(name,age){ console.log(`I'm${this.name}.${this.age}yearsold.`) } } letperson=newPerson('Teagan',22); person.student(); //I'mTeagan.22yearsold. //用平常class的寫法,不實體化所需類別的實例就不能被呼叫! Person.student('Teagan','22') //UncaughtTypeError:Person.studentisnotafunction Getter與Setter get():get語法會將物件屬性綁定到在查找該屬性時將呼叫的函式。

set():set語法將物件屬性綁定到要呼叫的函式。

只有遇到私有變數(_)時,才需用Getter與Setter取得或設定值。

需注意Getter沒有參數傳入,Setter只有一個參數: classPerson{ constructor(name){ this.name=name; } getage(){ if(this._age!==undefined){ return(`${this.name}'sageis${this._age}`) }else{ return('Validage!') } } setage(age){ this._age=age; } } letperson=newPerson('Teagan') person.age=22;//賦值 console.log(person.age);//"Teagan'sageis22" 參考資料: Object-orientedProgrammingin7minutes|Mosh 初學者應知道的物件導向JavaScript WhatAreJavaScriptConstructorFunctions? Day10:ES6篇-Class(類別) JavaScript|ES6中最容易誤會的語法糖Class-基本用法 [教學]深入淺出JavaScriptES6Class(類別) Classbasicsyntax-JAVASCRIPT.INFO setter-MDN geter-MDN Classes-MDN #javascript #OOP #constructor #class #super #extends TeaganHsu Follow Following 大學生 RelatedPosts [css]如果只有一個div vii120 CSS保健室|border-image-repeat itiswonderfall FunctionalProgramming筆記 JingTeng Comments Submit SignIntojoininthediscussion. Edit Submit Edit Submit Reply Submit



請為這篇文章評分?