摘要:特質是的一個重要的特性,主要的使用方式有兩個方面拓寬瘦接口為胖接口。定義可堆疊的改變。相對于多重繼承而言最靈活的一方面就是所指定的對象只有到被混入之后才能確定。
特質(trait)是scala的一個重要的特性,主要的使用方式有兩個方面:1.拓寬瘦接口為胖接口。2.定義可堆疊的改變。
trait相對于多重繼承而言最靈活的一方面就是super所指定的對象只有到被混入之后才能確定。
因為特質里面既可以有字段方法,還可以既只寫方法的類型,也可以寫上方法的實現(不像JAVA的接口那樣),而且可以混入到類中,類也可以使用任意多的特質。相當的靈活。
就混入到類中,和胖瘦接口而言,對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)//先執行Filtering,-1 被過濾掉了 queue1.put(0) // 執行過濾,然后 +1,然后 *2 queue1.put(1) println(queue1.get()) println(queue1.get())
javascript的實現:
代碼鏈接: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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78052.html
摘要:函數式編程與面向對象編程的類型關聯之劍目錄類型關聯關鍵字里的類型,除了在定義時會產生類型,還可以通過關鍵字來聲明類型。復合類型與關鍵字這種形式的類型稱為復合類型或者也叫交集類型。 函數式編程與面向對象編程[4]:Scala的類型關聯Type Alias 之劍 2016.5.4 23:55:19 類型關聯 Type Alias type關鍵字 scala里的類型,除了在定義clas...
摘要:編程語言將函數作為一等公民,函數可以被作為參數或者返回值傳遞,因為它被視為對象。是表示已注釋接口是函數接口的注釋。如果一個函數有一個或多個參數并且有返回值呢為了解決這個問題,提供了一系列通用函數接口,在包里。 【編者按】雖然 Java 深得大量開發者喜愛,但是對比其他現代編程語言,其語法確實略顯冗長。但是通過 Java8,直接利用 lambda 表達式就能編寫出既可讀又簡潔的代碼。作者...
摘要:第一節函數式范式什么是函數式編程函數式編程英語或稱函數程序設計,又稱泛函編程,是一種編程范型,它將電腦運算視為數學上的函數計算,并且避免使用程序狀態以及易變對象。 第一節 函數式范式 1. 什么是函數式編程 函數式編程(英語:functional programming)或稱函數程序設計,又稱泛函編程,是一種編程范型,它將電腦運算視為數學上的函數計算,并且避免使用程序狀態以及易變對...
摘要:判斷是否存在構造函數,不存在直接實例化,存在則通過來獲取輸入函數,并有相應的方法解決依賴參數問題,實現依賴注入。 Laravel 框架關鍵技術解析·讀書筆記(一) 第一章 入口文件 請求訪問的入口文件,主要完成幾部分工作,分別是: 自動加載函數的添加 服務器實例化與服務注冊 路由加載 請求實例化與路由分發 相應生成與發送 其中,自動加載函數用于包含引用文件,改文件是composer...
摘要:比如對一個數據流進行過濾映射以及求和運算,通過使用延后機制,那么所有操作只要遍歷一次,從而減少中間調用。這里需知道中的元素都是延遲計算的,正因為此,能夠計算無限數據流。 【編者按】在之前文章中,我們介紹了 Java 8和Scala的Lambda表達式對比。在本文,將進行 Hussachai Puripunpinyo Java 和 Scala 對比三部曲的第二部分,主要關注 Stream...
閱讀 2774·2021-11-22 15:11
閱讀 3537·2021-09-28 09:43
閱讀 2889·2019-08-30 13:05
閱讀 3431·2019-08-30 11:18
閱讀 1447·2019-08-29 16:34
閱讀 1302·2019-08-29 13:53
閱讀 2908·2019-08-29 11:03
閱讀 1658·2019-08-29 10:57