摘要:面向對象的三大特點封裝,繼承,多態缺一不可。構造函數,是一種特殊的方法。特別的一個類可以有多個構造函數,可根據其參數個數的不同或參數類型的不同來區分它們即構造函數的重載。
一、基本概念和背景
面向對象程序設計(OOP:Object-oriented programming)是一種程序設計范型,同時也是一種程序開發的方法。對象指的是類的實例。
面向對象(Object Oriented,OO)是一種對現實世界理解和抽象的方法,是計算機編程技術[1] 發展到一定階段后的產物。
面向對象的三大特點(封裝,繼承,多態)缺一不可。通常“基于對象”是使用對象,但是無法利用現有的對象模板產生新的對象類型,繼而產生新的對象,也就是說“基于對象”沒有繼承的特點。而“多態”表示為運行時類型確定(父類類型的子類對象實例),動態綁定執行對象,沒有了繼承的概念也就無從談論“多態”。
示例:繪制一個圖形,圖形已有為三角形、圓;
Java 示例
// 父類:抽象、封裝 public class Graph { void draw() { System.out.println("draw a Graph"); } }
// 繼承:子類type1 public class Triangle extends Graph { @Override void draw() { System.out.println("draw a Triangle"); } } // 繼承:子類type2 public class Circle extends Graph { @Override void draw() { System.out.println("draw a Circle"); } }
// 多態:運行時類型確定 public class Drawer { static void draw(Graph a) { a.draw(); } // 運行調用 public static void main(String args[]) { Graph p = new Triangle(); Drawer.draw(p); // "draw a Triangle" p = new Circle(); Drawer.draw(p); //"draw a Circle" }
Javascript ES5示例
// 封裝 function Graph(){} Graph.prototype.draw = function (){ console.log("draw a Graph"); } // 原型鏈引用 function Trianggle(){} Trianggle.prototype = new Graph(); Trianggle.prototype.draw = function (){ console.log("draw a Trianggle"); } // 原型鏈引用 function Circle(){} Circle.prototype = new Graph(); Circle.prototype.draw = function (){ console.log("draw a Circle"); }
// 相對多態:無顯示對象類型 function Drawer(obj){ obj.draw(); } // 運行時類型確定 var p = new Trianggle(); Drawer(p); p = new Circle(); Drawer(p);
大多面向對象語言中,面向對象一般基于面向’類‘的設計。類是代碼抽象的模式之一:實例化(instantiation)、繼承(inheritance)、和 (相對)多態(polymorphism)。類和實例的關系好比房屋建造。建筑師會繪制建筑藍圖,建筑工人根據藍圖落地成實際建筑,建筑就是藍圖的復制(概念和物理上的復制)。類就是建筑的抽象,含有一個建筑的所有特性。實例就是實際的建筑,包含了門、窗以及實際材料、地理位置。類通過復制操作被實例化為對象形式,實例間無直接關系。但這無法直接對應到 JavaScript 的實現機制,因為 Javascript 沒有實質類的概念,ES6的 class也是一種語法糖1。
二、JavaScript 封裝方法面向對象編程強調的是數據和操作數據行為的的相互關聯,因此最好的設計就是把數據和它相關的行為打包(封裝)起來。
封裝(Encapsulation)是指一種將抽象性函數式接口的實現細節部份包裝、隱藏起來的方法。
2.2 封裝模式(創建對象模式) 構造函數2 & 原型鏈(1) 良好的封裝能降低耦合度
(2) 方面數據統一管理、對象內部結構靈活修改
(3) 對其成員有更精確的控制,易于擴展
(4) 隱藏實現信息、細節,只暴露需要的 API
(1)工廠模式 - 函數 【內部對象創建屬性方法并返回對象,使用this】
function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); } return o; } var person1 = createPerson(“John”, 18, “Teacher"); var person2 = createPerson(“Greg”, 30, “Doctor”);
(2) 構造函數模式【內部 this創建屬性、方法;無 return; 通過改變 this指向創建實例】
**原生構造函數**:隱式創建對象,屬性、方法賦值給 this對象,無 return;
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); } } var person1 = new Person(“John”, 18, “Teacher"); var person2 = new Person(“Greg”, 30, “Doctor”);
構造函數: new 顯示創建 對象
步驟1: 創建一個新對象
步驟2:講構造函數的作用是賦值給新對象 (this 只向新對象 詞法作用域發生改變)
步驟3:執行構造函數的代碼 (為新對象 添加屬性 )
步驟4:返回新對象
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); } }
構造函數作為函數; 問題:作用域改變,每個傳入的對象重建一遍;)
var person1 = new Object();
Person.call( person1, “John”, 18, “Teacher");
var person2 = new Person(“Greg”, 30, “Doctor”);
(3) 原型模式 【原型對象創建屬性、方法】
構造函數無傳參, 共享原型對象的屬性,其中一個實例對原型對象的引用類型屬性做修改,影響所有其他實例對該屬性的使用; (* 引用類型屬性受影響 內存分配機制不同引起)
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 27; Person.prototype.job = "Doctor"; Person.prototype.friends = ["Lily", "John", "Alex"] Person.prototype.sayName = function() { console.log(this.name); } Person.prototype.getFriends = function() { console.log(this.friends); }
var person1 = new Person(); person1.name = "person1"; var person2 = new Person(); person2.name = "person2"; person2.sayName(); //“person2" person2.getFriends(); // ["Lily", "John", "Alex"] person1.friends.push(“Van"); person1.sayName(); //“person1" person2.getFriends(); //["Lily", "John", "Alex", "Van"]
(4) 構造函數 & 原型模式結合 【構造函數獨立屬性方法,原型對象創建公用屬性、方法】
好處:構造函數模式 定義實例個性化屬性;原型模式定義方法和共享屬性;功能模塊化 職責單一
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = [‘Lily", "John", "Alex"]; } Person.prototype ={ constructor: Person, sayName: function(){ alert(this.name); } } var person1 = new Person("Nicholas", 29, "Software Engineer"); person1.friends.push("Van"); var person2 = new Person(“Greg", 27, "Doctor");
(5) 動態原型模式 (使用:功能模塊化)【構造函數獨立屬性方法,原型對象按需創建公用屬性、方法】
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = [‘Lily’, "John", "Alex"]; if(typeof this.sayName != ‘function’){ Person.prototype.sayName = function(){ alert(this.name); }; } }
(6) 寄生構造函數模式 -【 已有對象擴展 - 原型鏈 】 (使用:第三方庫擴展 )
1.寫法上和工廠模式一樣 調用時多加 new 2.此模式創建的對象 與構造函數無關系, instanceof操作符無意義
function Person(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); } return o; } // 工廠模式 // var person1 = Person(“John”, 18, “Teacher”); // 寄生模式 var friend = new Person(“John”, 18, “Teacher”); // 返回新對象的實例
(7) 穩妥模式 【 內部建對象不用 this 閉包 - 詞法作用域 】(穩妥對象-無公共屬性,方法不引用 this)(使用:適用于安全環境 - 禁用 this 和 new)
1.寫法上和寄生模式類似 , 除方法不使用 this 2.此模式創建的對象 與構造函數無關系, instanceof操作符無意義
function Person(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(name); //無 this } return o; } var friend = Person(“John”, 18, “Teacher”); //無 new
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89537.html
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:一面向對象編程面向對象編程是一種抽象方式創建模型的編程方式。繼承我們實現一個子類,繼承汽車類將類的屬性和方法賦值給繼承汽車類的原型鏈創建子類實例以上是中的面向對象編程的簡單介紹,如有錯誤,歡迎指出。 一.面向對象編程面向對象編程(OOP--Object Oriented Programming)是一種抽象方式創建模型的編程方式。繼承,封裝,多態是OOP的三大基本特征。許多主流編程語言都...
閱讀 1252·2021-09-01 10:30
閱讀 2126·2021-07-23 10:38
閱讀 901·2019-08-29 15:06
閱讀 3159·2019-08-29 13:53
閱讀 3281·2019-08-26 11:54
閱讀 1834·2019-08-26 11:38
閱讀 2376·2019-08-26 10:29
閱讀 3132·2019-08-23 18:15