摘要:上一篇文章距離有出不多一個(gè)多月了現(xiàn)在好不容易有了好心情繼續(xù)看書寫點(diǎn)感悟第三章講述的是封裝像可以通過關(guān)鍵字來聲明一個(gè)方法使得只有該對(duì)象內(nèi)部的代碼才能執(zhí)行它在中沒有這樣的關(guān)鍵字但是可以使用閉包來創(chuàng)建只允許從對(duì)象內(nèi)部訪問的方法和屬性相比于閉包走了
上一篇文章講到接口模式是許多其他js設(shè)計(jì)模式的基礎(chǔ),它定義了兩個(gè)對(duì)象間的關(guān)系,接口不變那么關(guān)系的雙方可以被替換,不一定非得使用像第二章那樣嚴(yán)格的接口,而且應(yīng)該避免公開定義于接口中的方法,否則其他對(duì)象可能會(huì)對(duì)那些并不屬于接口的方法產(chǎn)生依賴,不安全,因?yàn)檫@些方法隨時(shí)都可能改變或者被刪除.一個(gè)理想軟件系統(tǒng)應(yīng)該未所有類定義接口,這些類只向外界提供他們實(shí)現(xiàn)的接口中規(guī)定的方法,任何別的方法都留作自用.其所有屬性都是私有的,外界只能通過接口中定義的存取方法進(jìn)行操作.
創(chuàng)建對(duì)象的基本模式有3種,門戶大開型只能提供公用成員;第二種,使用下劃線來表示方法或者屬性的私有性;第三種,通過閉包來創(chuàng)建真正私有的成員,這些成員只能通過特權(quán)方法訪問.以Book 類為例 -- 一個(gè)用來存儲(chǔ)關(guān)于一本書的數(shù)據(jù)的類,并為其實(shí)現(xiàn)一個(gè)以 HTML 形式顯示這些數(shù)據(jù)的方法.現(xiàn)在只需創(chuàng)建這個(gè)類, 下面是其他人在創(chuàng)建并使用實(shí)例:
//Book(isbn, title, author) var jsDesignPatterns = new Book("978-7-115-19128-1", "JavaScript 設(shè)計(jì)模式", "Harmes, R."); jsDesignPatterns.display(); //Outputs the data by creatingand populating an HTML element.門戶大開型對(duì)象
實(shí)現(xiàn) Book 類最簡(jiǎn)單的做法是按傳統(tǒng)方式創(chuàng)建一個(gè)類,用一個(gè)函數(shù)來做其構(gòu)造器.他的所有屬性和方法都公開可訪問,這些公用屬性需要使用 this 關(guān)鍵字來創(chuàng)建:
var Book = function(isbn, title, author) { if (isbn == undefined) { throw new Error("Book constructor requires an isbn."); this.isbn = isbn; this.title = title || "No title specified"; this.author = author || "No author specified"; } Book.prototype.display = function () { ... }; }
在構(gòu)造器中,isbn 必選, 因?yàn)?display 方法要求 book 對(duì)象都有一個(gè)準(zhǔn)確的 isbn,否則就不能找到相應(yīng)的圖片,也不能生成一個(gè)用于購書的鏈接.title 和 author 參數(shù)都是可選的,要有默認(rèn)值以防它們未被提供.
有個(gè)最大的問題,沒有辦法檢查 isbn 數(shù)據(jù)的完整性,錯(cuò)誤的 isbn 數(shù)據(jù)可能導(dǎo)致 display 方法失效.下面的版本強(qiáng)化了對(duì) isbn 的檢查:
var Book = function(isbn, title, author) { if (!this.checkIsbn(isbn)) { throw new Error("Book: Invalid ISBN."); } this.isbn = isbn; this.title = title || "No title specified"; this.author = author || "No author specified"; } Book.prototype ={ checkIsbn: function(isbn) { if(isbn == undefined || typeof isbn != "string") { return false; } isbn = isbn.replace(/-/, "");// Remove dashes. if(isbn.length != 10 && isbn.length != 13) { return false; } var sum =0; if (isbn.length === 10) { // 10 digit ISBN. if (!isbn.match(/^d{9}/)) { // Ensure characters 1 through 9 are digits. return false; } for (var i = 0; i < 9; i++) { sum += isbn.charAt(i) * (10 - i); } var checksum= sum % 11; if (checksum === 10){ checksum = "X"; } if (isbn.charAt(9) != checksum) { return false; } } else { // 13 digit ISBN. if (!isbn.match(/^d{12}/)) { // Ensure characters 1 through 12 are digits. return false; } for (var i = 0; i < 12; i++) { sum += isbn.charAt(i) * ((i % 2 === 0) ? 1 : 3); } var checksum = sum % 10; if (isbn.charAt(12) != checksum) { return false; } } return false; // All tests passed. }, display: function () { ... } };
checkIsbn 方法可以保證 ISBN 是一個(gè)具有正確位數(shù)和校驗(yàn)和的字符串.因?yàn)锽ook 類現(xiàn)在有兩個(gè)方法,所以 Book.prototype 被設(shè)置為一個(gè)對(duì)象字面量,這樣在定義多個(gè)方法的時(shí)候就不用在每個(gè)方法前面都加上Book.prototype.
現(xiàn)在保證了 display 方法可以正常工作,出現(xiàn)了另一個(gè)問題,假設(shè)一本書可能會(huì)有多個(gè)版本,每個(gè)版本都有自己的 ISBN,在實(shí)例化book對(duì)象之后直接修改 isbn 屬性:
jsDesignPatterns.isbn = "978-0261103283"; jsDesignPatterns.display();
所以即使在構(gòu)造器中對(duì)數(shù)據(jù)完整性進(jìn)行檢驗(yàn),還是無法阻止其他人給 isbn賦值,為了保護(hù)內(nèi)部數(shù)據(jù),為每個(gè)屬性提供 accessor 取值器和 mutator 賦值器方法.通過使用賦值器,你可以在把一個(gè)新值真正賦給屬性之前進(jìn)行各種檢驗(yàn).下面是加入了取值器合賦值器之后的新版 Book 對(duì)象:
var Publication = new Interface ("Publication", ["getIsbn", "getTitle", "setTitle", "getAuthor", "setAuthor", "display"]); var Book = function (isbn, title, author) { // implements Publication this.setIsbn(isbn); this.setTitle(title); this.setAuthor(author); } Book.prototype = { checkIsbn: function (isbn) { ... }, getIsbn: function () { return this.isbn; }, setIsbn: function (isbn) { if (!this.checkIsbn(isbn)) { throw new Error("Book: Invalid ISBN."); } this.isbn = isbn; }, getTitle: function () { return this.title; }, setTitle: function (title) { this.title = title || "No title specified"; }, getAuthor: function () { return this.author; }, setAuthor: function (author) { this.author = author || "No author specified"; }, diplay: function () { ... } };
上述代碼定義了一個(gè)接口,只需要使用這個(gè)接口中定義的方法與對(duì)象來打交道.還有一些對(duì)數(shù)據(jù)有保護(hù)作用的取值器,賦值器方法,以及一些檢驗(yàn)方法.
但是依然有缺陷:提供了賦值器方法,但那些屬性仍然是公開的,可以被直接設(shè)置.而且無法保護(hù)內(nèi)部數(shù)據(jù),取值器和賦值器方法也引入了較多代碼(js 文件大小較為重要).
依然是上面那個(gè) snippet,只不過 setAttributes 的時(shí)候所有要設(shè)置的屬性和方法都加上了 下劃線_ 前綴,表示它是私用屬性和方法(js 中可以使用下劃線和字母開頭命名出有效變量).
下劃線的這種用法表明一個(gè)屬性或者方法僅供對(duì)象內(nèi)部使用,直接訪問它或者設(shè)置它可能會(huì)導(dǎo)致意想不到的后果,這有助于防止程序員對(duì)它的無意使用,卻不能防止有意使用使用.
這個(gè)規(guī)范只有在得到遵守時(shí)才有效果,并不是真正可以用來隱藏對(duì)象內(nèi)部數(shù)據(jù)的解決方案,主要適用于非敏感性的內(nèi)部方法和屬性.
在討論這種真正的私用性方法和屬性的實(shí)現(xiàn)技術(shù)之前,我們先鞏固一下相關(guān)基礎(chǔ).在 js 中,只有函數(shù)具有作用域,在一個(gè)函數(shù)內(nèi)部聲明的變量在函數(shù)外部無法訪問,私用屬性也是希望無法在對(duì)象外部訪問的變量,所以作用域相關(guān)性明顯.定義在一個(gè)函數(shù)中的變量在該函數(shù)中的內(nèi)嵌函數(shù)是可以訪問的.
function foo() { var a = 10; function bar() { a *= 2; } bar(); return a; }
a定義在函數(shù)foo中,但函數(shù) bar 可以訪問它,因?yàn)?bar 也定義在 foo 中,bar 內(nèi)部對(duì) a 賦新值,當(dāng) bar 在 foo 中被調(diào)用時(shí)它能夠訪問 a,這可以理解.如果 bar 在 foo 外部被調(diào)用呢
function foo() { var a = 10; function bar () { a *= 2; return a; } return bar; } var baz = foo(); // baz is now a reference to functionbar. baz(); // return 20; baz(); // return 40; baz(); // return 80; var blat = foo(); // blat is another reference to bar. blat(); // return 20, because a new copy of a is being used.
在上述代碼中, 所返回的對(duì) bar 函數(shù)的引用被賦給變量 baz.這個(gè)函數(shù)現(xiàn)在是在 foo 外部被調(diào)用,但他依然能夠訪問 a.這是因?yàn)?js 中的作用域是詞法性的,函數(shù)是運(yùn)行在定義他們的作用域中(本例中是 foo 內(nèi)部的作用域),而不是運(yùn)行在調(diào)用他們的作用域中,只要 bar 被定義在 foo 中,他就能訪問在 foo 中定義的所有變量, 即時(shí) foo 的執(zhí)行已經(jīng)結(jié)束.
在 foo 返回后,它的作用域被保存下來,但是只有他返回的那個(gè)函數(shù)能夠訪問這個(gè)作用域.baz和 blat 各有這個(gè)作用域及 a 的一個(gè)副本,而且只有他們自己能對(duì)其進(jìn)行修改.返回一個(gè)內(nèi)嵌函數(shù)是創(chuàng)建閉包最常用的手段.
現(xiàn)在有了對(duì)閉包的理解之后再來討論一下我們剛剛要做的事: 需要?jiǎng)?chuàng)建一個(gè)只能在對(duì)象內(nèi)部訪問的變量.借助于閉包你可以創(chuàng)建只允許特定函數(shù)訪問的變量,而且這些變量在這些函數(shù)的各次調(diào)用之間依然存在.為了創(chuàng)建私用屬性,你需要在構(gòu)造器函數(shù)的作用域中定義相關(guān)變量,這些變量可以被定義于該作用域中的所有函數(shù)訪問,包括哪些特權(quán)方法:
var Book = function(newIsbn, newTitle, newAuthor){ // implements Punlication // Private attribute. var isbn, title, author; // Private method. function checkIsbn(isbn) { ... } // Privilleged methods. this.getIsbn = function (){ return isbn; }; this.setIsbn =function (newIsbn) { if (!checkIsbn(newIsbn) { throw new Error("Book: Invalid ISBN."); } isbn =newIsbn; }; this.getTitle = function () { return title; }; this.setTitle = function (newTitle) { title = newTitle || "No title specified"; }; this.getAuthor = function () { return author; }; this.setAuthor = function (newAuthor) { author = newAuthor || "No author specified"; }; // Constructor code. this.setIsbn(newIsbn); this.setTitle(newTitle); this.setAuthor(newAuthor); }; // Public, non-privileged methods. Book.prototype = { display: function () { ... } };
以上代碼和之前的創(chuàng)建對(duì)象模式有什么不同呢,其他情況下我們?cè)趧?chuàng)建和引用對(duì)象的屬性時(shí)總要使用 this 關(guān)鍵字.但是這個(gè)地方我們用 var 聲明這些屬性變量,它們只存在于Book 構(gòu)造器中,checkIsbn 函數(shù)是私有方法.
需要訪問這些變量和函數(shù)的方法只需聲明在 Book 中,被稱作特權(quán)方法(privileged method),他們是公有方法,之所以有 特權(quán)方法前面都用 this 關(guān)鍵詞來幫助聲明, 是為了在對(duì)象外部能夠被訪問.這些方法定義于 Book 構(gòu)造器的作用域中,所以它們能夠訪問到私有屬性,引用這些屬性時(shí)并沒有使用 this關(guān)鍵詞,因?yàn)樗麄儧]有公開.所有取值器和賦值器方法都被改為不加 this 的直接引用這些屬性.
任何不需要直接訪問私用屬性的方法都可以像原來那樣在 Book.prototype中聲明.display 就是這類方法中的一個(gè),他可以通過調(diào)用 getIsbn或者 getTitle等等特權(quán)方法來間接訪問任何私用屬性.只有那些需要直接訪問私用成員的方法才是特權(quán)方法.需要注意的是,特權(quán)方法太多會(huì)占用較多內(nèi)存.每個(gè)對(duì)象實(shí)例都包含了所有特權(quán)方法的新副本.
用閉包方式創(chuàng)建的對(duì)象可以具有真正的私有屬性,其他程序員不可能直接訪問它們創(chuàng)建的Book 實(shí)例的任何內(nèi)部數(shù)據(jù).
但是,,,這樣使用閉包還是有缺點(diǎn)的.之前的門戶大開型對(duì)象創(chuàng)建模式中,所有方法都創(chuàng)建在原型對(duì)象中,因此不管生成多少對(duì)象實(shí)例,這些方法在內(nèi)存中只存在一份.而在本節(jié)中每生成一個(gè)新的對(duì)象實(shí)例都將 copy 每一個(gè)私有方法和特權(quán)方法,,,這樣就會(huì)帶來更多內(nèi)存消耗,所以只適合用在真正私有成員的場(chǎng)合.這種對(duì)象創(chuàng)建模式也不利于派生子類,因?yàn)樗缮龅淖宇惒荒茉L問超類的任何私有屬性或者方法.
所以在 js 中用閉包實(shí)現(xiàn)私有成員導(dǎo)致的派生問題被稱作**"繼承破壞封裝(inheritance breaks encapsulation)",如果你創(chuàng)建的類以后可能會(huì)需要派生出子類, 那么最好還是采用前兩種對(duì)象創(chuàng)建模式.
剛才講的作用域和閉包可用于創(chuàng)建靜態(tài)成員(公有和私有),大多數(shù)方法和屬性所關(guān)聯(lián)的是類的實(shí)例,但是靜態(tài)成員所關(guān)聯(lián)的是類本身.也就是說,靜態(tài)成員是在類的層次上操作,不是實(shí)例層次上.每個(gè)靜態(tài)成員都只有一份,是通過類對(duì)象方法的.
下面是添加了靜態(tài)屬性和方法和 Book 類:
var Book = (function () { // Private static attributes. var numOfBooks = 0; // Private static method. function checkIsbn(isbn) { ... } // Return the constructor. return function(newIsbn, newTitle, newAuthor) { // implements Publication // Private attributes. var isbn; var title; var author; //Privileged methods. this.getIsbn =function () { return isbn; }; this.setIsbn = function(newIsbn) { if (!checkIsbn(newIsbn)) { throw new Error("Book: Invalid ISBN."); isbn = newIsbn; }; } this.getTitle = function () { return title; }; this.setTitle = function (newTitle) { title = newTitle || "No title specified"; }; this.getAuthor = function () { return author; }; this.setAuthor = function (newAuthor) { title = newAuthor || "No title specified"; }; // Constructor code. numOfBooks++; // Keep track of how many Books have been instantiated with the private static attribute. if (numOfBooks > 50) { throw new Error("Book: Only 50 instances of Book can be created."); } this.setIsbn(newIsbn); this.setTitle(newTitle); this.setAuthor(newAuthor); } })(); // Public static method. Book.convertToTitleCase = function(inputString) { ... }; // Public, non-privileged methods. Book.prototype ={ display: function () { ... } };
與前一節(jié)創(chuàng)建的類大題相似,但是有重要區(qū)別.這里的私有成員和特權(quán)方法仍然聲明在構(gòu)造器中(分別使用 var 和 this 關(guān)鍵字),但是那個(gè)構(gòu)造器卻從原來的普通函數(shù)辦成了一個(gè)內(nèi)嵌函數(shù),并且被作為包含它的函數(shù)的返回值賦給變量 Book.這里創(chuàng)建了一個(gè)閉包,里面聲明了靜態(tài)的私有成員.位于外層函數(shù)聲明之后的一對(duì)空括號(hào)很重要 -- 代碼一載入就立即執(zhí)行這個(gè)函數(shù)(而不是在調(diào)用 Book 構(gòu)造函數(shù)時(shí)),這個(gè)函數(shù)的返回值是另一個(gè)函數(shù),被賦值給 Book 變量 -- 一個(gè)構(gòu)造函數(shù),在實(shí)例化 Book 時(shí),所調(diào)用的是這個(gè)內(nèi)層函數(shù),外層函數(shù)只是用于創(chuàng)建一個(gè)可以用來存放靜態(tài)私有成員的閉包.
私有的靜態(tài)成員可以從構(gòu)造器內(nèi)部訪問,這意味著所有私有函數(shù)和特權(quán)函數(shù)都能訪問它們.與其他方法相比,他們?cè)趦?nèi)存中只會(huì)存放一份.
因?yàn)樗鼈冊(cè)跇?gòu)造器之外,所以不是特權(quán)方法,不能訪問任何定義在構(gòu)造器中的私有屬性.定義在構(gòu)造器中的私有方法能夠調(diào)用那些私有靜態(tài)方法.
要判斷一個(gè)私有方法是否應(yīng)該被設(shè)計(jì)成靜態(tài)方法,主要看它是否需要訪問任何實(shí)例數(shù)據(jù),如果不需要那么設(shè)計(jì)成靜態(tài)方法更省內(nèi)存.
在 js 中,可以通過創(chuàng)建只有取值器而沒有賦值器的私有變量來模仿常量,而且不因?qū)ο髮?shí)例的不同而變化,所以將其作為私有靜態(tài)屬性來設(shè)計(jì)是合乎情理的.
假設(shè) Class 對(duì)象有一個(gè) UPPER_BOUND的常量,那么為了獲取這個(gè)常量而進(jìn)行的方法調(diào)用
Class.getUPPER_BOUND();
為了實(shí)現(xiàn)這個(gè)取值器,需要使用特權(quán)靜態(tài)方法:
var Class = (function() { // Constants (created as private static attributes). var UPPER_BOUND = 100; // Constructor. var ctor = function (constructorArgument) { ... }; // Privileged static method. ctor.getUPPER_BOUND = function () { return UPPER_BOUND; }; // Return the constructor. return ctor; })();
如果需要許多常量,可以創(chuàng)建一個(gè)通用的取值器方法,這樣就不必為每個(gè)常量都創(chuàng)建取值器方法:
var Class = (function () { // Private static attributes. var constants = { UPPER_BOUND: 100, LOWER_BOUND: -100 }; // Constructor. var ctor = function(constructorArgument) { ... }; // Privileged static method. ctor.getConstant = function(name) { return constants[name]; } ... // Return the constructor. return ctor; })();單體和對(duì)象工廠
這兩個(gè)模式就是使用閉包來創(chuàng)建受保護(hù)的變量空間.后面會(huì)慢慢涉及,在此先簡(jiǎn)要介紹一下,單體模式使用一個(gè)外層函數(shù)返回的對(duì)象字面量來公開特權(quán)成員,而私用成員則被保護(hù)性地封裝在外層函數(shù)的作用域中,主要原理是:外層函數(shù)在定義后立即執(zhí)行,其結(jié)果被賦給一個(gè)變量.前面的例子中外層函數(shù)返回的都是一個(gè)函數(shù),而單體模式中外層函數(shù)返回的是一個(gè)對(duì)象字面量.
對(duì)象工廠可以使用閉包來創(chuàng)建具有私有成員的對(duì)象.最簡(jiǎn)形式是一個(gè)類構(gòu)造器.
保護(hù)了內(nèi)部數(shù)據(jù)的完整性,通過講數(shù)據(jù)的訪問途徑限制為取值器和賦值器這兩個(gè)方法,可以獲得對(duì)取值和賦值的完全控制.這樣可以減少其他函數(shù)所需要的錯(cuò)誤檢查代碼數(shù)量,并且確保數(shù)據(jù)不會(huì)處于無效狀態(tài).另外,對(duì)象的重構(gòu)可以變得更輕松.因?yàn)橛脩舨恢缹?duì)象的內(nèi)部細(xì)節(jié),所以可以隨心所欲的修改對(duì)象內(nèi)部使用的數(shù)據(jù)結(jié)構(gòu)和算法.
通過只公開那些在接口中規(guī)定的方法,可以弱化模塊間的耦合.盡可能的提高對(duì)象的獨(dú)立性可以帶來許多好處:提高對(duì)象的可重用性,使其在必要的時(shí)候可以被替換.使用私有變量可以避免空間沖突,如果一個(gè)變量在代碼中其他地方都不能被訪問,就不用擔(dān)心它是否與程序中其他地方的對(duì)象或者函數(shù)重名,大幅改動(dòng)對(duì)象的內(nèi)部細(xì)節(jié)也不會(huì)影響其他代碼.
封裝也存在一定的缺憾.比如,私有方法很難進(jìn)行單元測(cè)試.因?yàn)樗麄冞€有其內(nèi)部變量都是私有的,在對(duì)象外部沒法訪問.
要么通過使用公有方法來提供訪問途徑(這樣就市區(qū)許多私有方法的好處),要么設(shè)法在對(duì)象內(nèi)部定義并執(zhí)行所有單元測(cè)試.最好的解決辦法是只對(duì)公有辦法進(jìn)行單測(cè).可以覆蓋到所有私有方法,但是卻是間接的.這種問題不是 js 特有的,只對(duì)公有方法進(jìn)行單測(cè)較易接受
作用域鏈復(fù)雜的話可能會(huì)使錯(cuò)誤調(diào)試更加困難,有時(shí)候很難區(qū)分來自不同作用域的許多同名變量.此問題不是經(jīng)過封裝的對(duì)象所特有的,但是實(shí)現(xiàn)私有方法和屬性所有的閉包會(huì)讓它變得更加復(fù)雜.
過度封裝可能會(huì)損害類的靈活性,不利于和小伙伴之間的合作,他可能對(duì)你的類的需求了解的并不透徹.
-最大的問題在于 js 實(shí)現(xiàn)封裝較為困難.不利于新手使用.js 與大多數(shù)面向?qū)ο笳Z言不同,封裝涉及的調(diào)用鏈和定義后立即執(zhí)行的匿名函數(shù)等概念加大了學(xué)習(xí)難度.
小結(jié)本文討論了信息隱藏的概念以及如何使用封裝這種手段來實(shí)現(xiàn)它,js 沒有對(duì)封裝提供內(nèi)置的支持,所以需要依賴其他東西.
如果可以確信其他小伙伴只會(huì)使用接口中規(guī)定的方法,或者并非迫切需要保持內(nèi)部數(shù)據(jù)的完整性,那,那么可以使用門戶大開型對(duì)象.
命名規(guī)范用來告知小伙伴哪些方法是不宜直接方法的內(nèi)部方法.如果需要真正的私有成員,那么只能使用閉包.通過創(chuàng)建一個(gè)受保護(hù)的變量空間,可以實(shí)現(xiàn)公有,私有和特權(quán)成員,靜態(tài)成員,常量.理解 js 作用域的特點(diǎn),可以模仿出各種面向?qū)ο蠹夹g(shù).
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/80257.html
摘要:本文繼續(xù)講封裝。上一篇樂字節(jié)垃圾回收機(jī)制和語句這次講述繼承與權(quán)限修飾。通過繼承,子類自動(dòng)擁有了基類的所有成員成員變量和成員方法。一覽無遺子承父業(yè)兒子自己使用家庭和睦占為已有。 本文繼續(xù)講Java封裝。上一篇:樂字節(jié)Java|GC垃圾回收機(jī)制、package和import語句 這次講述JavaBean、繼承與權(quán)限修飾。showImg(https://segmentfault.com/im...
摘要:組件可以處理其他組件的實(shí)例化為了避免破壞封裝,請(qǐng)注意通過傳遞的內(nèi)容。因此,將狀態(tài)管理的父組件實(shí)例傳遞給子組件會(huì)破壞封裝。讓我們改進(jìn)兩個(gè)組件的結(jié)構(gòu)和屬性,以便恢復(fù)封裝。組件的可重用性和可測(cè)試性顯著增加。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長(zhǎng),不過內(nèi)容太過于吸引我,還是忍不住要翻譯出來。此篇文章對(duì)編寫可重用和可維護(hù)的Re...
摘要:聲明本文首發(fā)于我的個(gè)人微信公眾號(hào)編程社區(qū),查看更多文章與學(xué)習(xí)資源請(qǐng)移步我的公眾號(hào)編程社區(qū)今天我們來看看面向?qū)ο蟮娜筇卣髦环庋b下來我們從現(xiàn)實(shí)生活中的例子來聊聊封裝的特性我們?nèi)粘J褂玫碾娔X主機(jī),把內(nèi)存主板等等都封裝到機(jī)箱里面去。 聲明:本文首發(fā)于我的個(gè)人微信公眾號(hào)【Java編程社區(qū)】,查看更多文章與學(xué)習(xí)資源請(qǐng)移步我的公眾號(hào)Java編程社區(qū) 今天我們來看看面向?qū)ο蟮娜筇卣髦弧庋b ...
摘要:在中,并沒有對(duì)抽象類和接口的支持。例如,當(dāng)對(duì)象需要對(duì)象的能力時(shí),可以有選擇地把對(duì)象的構(gòu)造器的原型指向?qū)ο螅瑥亩_(dá)到繼承的效果。本節(jié)內(nèi)容為設(shè)計(jì)模式與開發(fā)實(shí)踐第一章筆記。 動(dòng)態(tài)類型語言 編程語言按數(shù)據(jù)類型大體可以分為兩類:靜態(tài)類型語言與動(dòng)態(tài)類型語言。 靜態(tài)類型語言在編譯時(shí)已確定變量類型,動(dòng)態(tài)類型語言的變量類型要到程序運(yùn)行時(shí),待變量被賦值后,才具有某種類型。 而JavaScript是一門典型...
閱讀 2248·2021-11-22 09:34
閱讀 2012·2021-09-22 15:22
閱讀 2015·2019-08-29 15:05
閱讀 2105·2019-08-26 10:43
閱讀 3406·2019-08-26 10:26
閱讀 876·2019-08-23 18:29
閱讀 3518·2019-08-23 16:42
閱讀 1994·2019-08-23 14:46