摘要:特質(zhì)是的一個重要的特性,主要的使用方式有兩個方面拓寬瘦接口為胖接口。定義可堆疊的改變。相對于多重繼承而言最靈活的一方面就是所指定的對象只有到被混入之后才能確定。
特質(zhì)(trait)是scala的一個重要的特性,主要的使用方式有兩個方面:1.拓寬瘦接口為胖接口。2.定義可堆疊的改變。
trait相對于多重繼承而言最靈活的一方面就是super所指定的對象只有到被混入之后才能確定。
因?yàn)樘刭|(zhì)里面既可以有字段方法,還可以既只寫方法的類型,也可以寫上方法的實(shí)現(xiàn)(不像JAVA的接口那樣),而且可以混入到類中,類也可以使用任意多的特質(zhì)。相當(dāng)?shù)撵`活。
就混入到類中,和胖瘦接口而言,對javascript來說簡直就是天生的,不值一提(但javascript的問題是,以弱類型換來的靈活,有時候總感覺靈活的都不像話,特別不容易理解其他jser的代碼)。
就[可堆疊的改變]而言:如下scala代碼:
import scala.collection.mutable.ArrayBuffer abstract class IntQueue { def get(): Int def put(x: Int) } class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer[Int] def get() = buf.remove(0) def put(x: Int) { buf += x } } // val queue = new BasicIntQueue // queue.put(10) // queue.put(20) // queue.get() // queue.get() trait Doubling extends IntQueue { abstract override def put(x: Int) { super.put(2 * x) } } class MyQueue extends BasicIntQueue with Doubling // val queue = new MyQueue // queue.put(10) // println(queue.get()) val queue = new BasicIntQueue with Doubling // queue.put(10) // println(queue.get()) trait Incrementing extends IntQueue { abstract override def put(x: Int) { super.put(x + 1) } } trait Filtering extends IntQueue { abstract override def put(x: Int) { if(x >= 0) super.put(x) } } val queue1 = new BasicIntQueue with Doubling with Incrementing with Filtering queue1.put(-1)//先執(zhí)行Filtering,-1 被過濾掉了 queue1.put(0) // 執(zhí)行過濾,然后 +1,然后 *2 queue1.put(1) println(queue1.get()) println(queue1.get())
javascript的實(shí)現(xiàn):
代碼鏈接:https://github.com/peichao01/test2/tree/master/javascript/trait
function trait (konstructor, traits) { traits = [].slice.call(arguments, 1); function _trait(reciever, trait_, parentName){ for(var methodName in trait_){ if(reciever.hasOwnProperty(methodName)){ var method = trait_[methodName]; if((typeof method == "function") && (typeof reciever[methodName] == "function") && (method.toString().indexOf(parentName) > -1)) { var baseMethod = reciever[methodName]; reciever[methodName] = function(){ var baseSaved = this[parentName]; this[parentName] = baseMethod; var result = method.apply(this, arguments); this[parentName] = baseSaved; return result; }; } else { reciever[methodName] = method; } } } } function mixinTrait (reciever) { for(var i = 0, len = traits.length; i < len; i++){ _trait(reciever, traits[i], "super"); } } function Constructor(){ konstructor.apply(this, arguments); mixinTrait(this); } for(var key in konstructor.prototype){ if(konstructor.prototype.hasOwnProperty(key)) Constructor.prototype[key] = konstructor.prototype[key]; } mixinTrait(Constructor.prototype); return Constructor; } function BasicIntQueue(name){ this.name = name; this._buf = []; } BasicIntQueue.prototype.get = function(){ return this._buf.shift(); }; BasicIntQueue.prototype.put = function(x){ this._buf.push(x); }; function BasicIntQueue2(name){ this.name = name; this._buf = []; this.get = function(){ return this._buf.shift(); }; this.put = function(x){ this._buf.push(x); }; } var trait_Doubling = { put: function(x){ this.super(2 * x); } }; var trait_Incrementing = { put: function(x){ this.super(x + 1); } }; var trait_Filtering = { put: function(x){ if(x >= 0) this.super(x); } }; var Klass = trait(BasicIntQueue2, trait_Doubling, trait_Incrementing, trait_Filtering); var queue = new Klass("Klass"); var queue1 = new BasicIntQueue("BasicIntQueue"); queue1.put(-1); queue.put(-1); queue.put(0); queue.put(1); console.log(queue.get()); // 2 console.log(queue.get()); // 4 console.log(queue.get()); // undefined
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78052.html
摘要:函數(shù)式編程與面向?qū)ο缶幊痰念愋完P(guān)聯(lián)之劍目錄類型關(guān)聯(lián)關(guān)鍵字里的類型,除了在定義時會產(chǎn)生類型,還可以通過關(guān)鍵字來聲明類型。復(fù)合類型與關(guān)鍵字這種形式的類型稱為復(fù)合類型或者也叫交集類型。 函數(shù)式編程與面向?qū)ο缶幊蘙4]:Scala的類型關(guān)聯(lián)Type Alias 之劍 2016.5.4 23:55:19 類型關(guān)聯(lián) Type Alias type關(guān)鍵字 scala里的類型,除了在定義clas...
摘要:編程語言將函數(shù)作為一等公民,函數(shù)可以被作為參數(shù)或者返回值傳遞,因?yàn)樗灰暈閷ο?。是表示已注釋接口是函?shù)接口的注釋。如果一個函數(shù)有一個或多個參數(shù)并且有返回值呢為了解決這個問題,提供了一系列通用函數(shù)接口,在包里。 【編者按】雖然 Java 深得大量開發(fā)者喜愛,但是對比其他現(xiàn)代編程語言,其語法確實(shí)略顯冗長。但是通過 Java8,直接利用 lambda 表達(dá)式就能編寫出既可讀又簡潔的代碼。作者...
摘要:第一節(jié)函數(shù)式范式什么是函數(shù)式編程函數(shù)式編程英語或稱函數(shù)程序設(shè)計(jì),又稱泛函編程,是一種編程范型,它將電腦運(yùn)算視為數(shù)學(xué)上的函數(shù)計(jì)算,并且避免使用程序狀態(tài)以及易變對象。 第一節(jié) 函數(shù)式范式 1. 什么是函數(shù)式編程 函數(shù)式編程(英語:functional programming)或稱函數(shù)程序設(shè)計(jì),又稱泛函編程,是一種編程范型,它將電腦運(yùn)算視為數(shù)學(xué)上的函數(shù)計(jì)算,并且避免使用程序狀態(tài)以及易變對...
摘要:判斷是否存在構(gòu)造函數(shù),不存在直接實(shí)例化,存在則通過來獲取輸入函數(shù),并有相應(yīng)的方法解決依賴參數(shù)問題,實(shí)現(xiàn)依賴注入。 Laravel 框架關(guān)鍵技術(shù)解析·讀書筆記(一) 第一章 入口文件 請求訪問的入口文件,主要完成幾部分工作,分別是: 自動加載函數(shù)的添加 服務(wù)器實(shí)例化與服務(wù)注冊 路由加載 請求實(shí)例化與路由分發(fā) 相應(yīng)生成與發(fā)送 其中,自動加載函數(shù)用于包含引用文件,改文件是composer...
摘要:比如對一個數(shù)據(jù)流進(jìn)行過濾映射以及求和運(yùn)算,通過使用延后機(jī)制,那么所有操作只要遍歷一次,從而減少中間調(diào)用。這里需知道中的元素都是延遲計(jì)算的,正因?yàn)榇?,能夠?jì)算無限數(shù)據(jù)流。 【編者按】在之前文章中,我們介紹了 Java 8和Scala的Lambda表達(dá)式對比。在本文,將進(jìn)行 Hussachai Puripunpinyo Java 和 Scala 對比三部曲的第二部分,主要關(guān)注 Stream...
閱讀 2830·2021-11-22 15:11
閱讀 3550·2021-09-28 09:43
閱讀 2896·2019-08-30 13:05
閱讀 3438·2019-08-30 11:18
閱讀 1454·2019-08-29 16:34
閱讀 1311·2019-08-29 13:53
閱讀 2916·2019-08-29 11:03
閱讀 1668·2019-08-29 10:57