成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

大數(shù)據(jù)Scala系列之特質(zhì)-創(chuàng)新互聯(lián)

大數(shù)據(jù)Scala系列之特質(zhì),特質(zhì)的定義除了使用關(guān)鍵字trait之外,與類定義無(wú)異。

為米脂等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及米脂網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站建設(shè)、成都網(wǎng)站制作、米脂網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

特質(zhì)用來(lái)在類之間進(jìn)行接口或者屬性的共享。類和對(duì)象都可以繼承特質(zhì),特質(zhì)不能被實(shí)例化,因此也沒(méi)有參數(shù)。

一旦特質(zhì)被定義了,就可以使用extends或者with在類中混入特質(zhì)。

1 作為接口使用的特質(zhì)
特質(zhì)的定義:

trait Logger{
//這是一個(gè)抽象方法,特質(zhì)中未被實(shí)現(xiàn)的方法默認(rèn)是抽象的,不需要abstract關(guān)鍵字修飾
def log(msg:String)
}

子類對(duì)特質(zhì)的實(shí)現(xiàn):

class ConsoleLogger extends Logger{
//重寫抽象方法,不需要override
def log(msg:String){println(msg)}
}

2 帶有具體實(shí)現(xiàn)的特質(zhì)
trait ConsoleLogger{
//注意與Java中接口的不同
def log(msg:String){println(msg)}
}

特質(zhì)的使用

class SavingAccount extends Account with ConsoleLogger{
def withdraw(amount:Double){
if(amount >balance) log("Insufficent funds")
else balance -= amount
}
}

3 帶有特質(zhì)的對(duì)象
scala自帶有Logged特質(zhì),但是沒(méi)有實(shí)現(xiàn)

trait Logged{
def log(msg:String){}
}

如果在類定義中使用了該特質(zhì)

//該類中,其中的日志信息不會(huì)被記錄
class SavingAccount extends Account with Logged{
def withdraw(amount:Double){
if(amount >balance) log("Insufficent funds")
else balance -= amount
}
}

標(biāo)準(zhǔn)的ConsoleLogger擴(kuò)展自Logger

class ConsoleLogger extends Logger{
//重寫抽象方法,不需要override
def log(msg:String){println(msg)}
}

可以在創(chuàng)建對(duì)象的時(shí)候,加入該特質(zhì):

val acct1=new SavingAccount with ConsoleLogger

這樣,創(chuàng)建同一類對(duì)象,卻可以加入不同的特質(zhì)

val acct2=new SavingAccount with FileLogger

4 多個(gè)疊加的特質(zhì)
可以為類或者對(duì)象添加多個(gè)互相調(diào)用的特質(zhì),特質(zhì)的執(zhí)行順序,取決于特質(zhì)被添加的順序

trait Logged{
def log(msg:String)
}
trait ConsoleLogger extends Logged{
//重寫抽象方法,不需要override
def log(msg: String) ={println(msg)}
}
//給log加上時(shí)間戳
trait TimestampLogger extends ConsoleLogger {
override def log(msg: String) {
super.log(s"${java.time.Instant.now()} $msg")
}
}
//截?cái)噙^(guò)于冗長(zhǎng)的日志信息
trait ShortLogger extends ConsoleLogger{
val maxLength = 15
override def log(msg: String) {
super.log(
if(msg.length <=maxLength)msg
else
s"${msg.substring(0,maxLength-3)}...")
}
}
//定義超類
class Account {
protected var balance:Double = 0
}
class SavingAccount extends Account with ConsoleLogger{
def withdraw(amount:Double){
if(amount >balance) log("Insufficent funds")
else balance = balance - amount
}
}

object test{
def main(args: Array[String]): Unit = {
val acct1 = new SavingAccount with ConsoleLogger with TimestampLogger with ShortLogger
val acct2 = new SavingAccount with ConsoleLogger with ShortLogger with TimestampLogger
acct1.withdraw(100.0)
acct2.withdraw(100.0)

}
}

//res:
//ShortLogger的log方法先被執(zhí)行,然后它的super.log調(diào)用的是TimestampLogger 的log方法,最后調(diào)用ConsoleLogger 的方法將信息打印出來(lái)
2018-06-15T16:50:28.448Z Insufficent ...
//先是TimestampLogger 的log方法被執(zhí)行,然后它的super.log調(diào)用的是ShortLogger的log方法,最后調(diào)用ConsoleLogger 的方法將信息打印出來(lái)
2018-06-15T1...

5 使用特質(zhì)統(tǒng)一編程
import scala.collection.mutable.ArrayBuffer

trait Pet {
val name: String
}

class Cat(val name: String) extends Pet
class Dog(val name: String) extends Pet

val dog = new Dog("Harry")
val cat = new Cat("Sally")

val animals = ArrayBuffer.empty[Pet]
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name)) // Prints Harry Sally

Mixins用于進(jìn)行類組合的特質(zhì):

abstract class A {
val message: String
}
class B extends A {
val message = "I'm an instance of class B"
}
//此處的特質(zhì)C即為mixin
trait C extends A {
def loudMessage = message.toUpperCase()
}
class D extends B with C

val d = new D
println(d.message) // I'm an instance of class B
println(d.loudMessage) // I'M AN INSTANCE OF CLASS B

6 當(dāng)做富接口使用的特質(zhì)
//注意抽象方法和具體方法的結(jié)合
trait Logger { def log(msg: String)
def info(msg: String) { log("INFO: " + msg) }
def warn(msg: String) { log("WARN: " + msg) }
def severe(msg: String) {log("SEVERE: " + msg)}
}
class Account {
protected var balance:Double = 0
}
class SavingsAccount extends Account with Logger {
def withdraw(amount: Double) {
if (amount > balance) severe("Insufficient funds") else "you can do this" }
override def log(msg: String) { println(msg) }
}

object test{
def main(args: Array[String]): Unit = {
val acc = new SavingsAccount
acc.withdraw(100)
}
}
//result
SEVERE: Insufficient funds

7特質(zhì)中的具體字段和抽象字段
特質(zhì)中的字段有初始值則就是具體的,否則是抽象的。

trait ShortLogger extends Logged {
val maxLength = 15 // 具體字段
}

那么繼承該特質(zhì)的子類是如何獲得這個(gè)字段的呢。Scala是直接將該字段放入到繼承該特制的子類中,而不是被繼承。例如:

class SavingsAccount extends Account with ConsoleLogger with ShortLogger {
var interest = 0.0
def withdraw(amount: Double) {
if (amount > balance) log("Insufficient funds")
else ...
}
}

特質(zhì)中的抽象字段在具體的子類中必須被重寫:

trait ShortLogger extends Logged {
val maxLength: Int//抽象字段
override def log(msg: String) {
super.log( if (msg.length <= maxLength) msg else msg.substring(0, maxLength - 3) + "...")
}
}

class SavingsAccount extends Account with ConsoleLogger with ShortLogger {
val maxLength = 20 // 不需要寫override
}

8 特質(zhì)構(gòu)造順序
特質(zhì)也是有構(gòu)造器的,由字段的初始化和其他特質(zhì)體中的語(yǔ)句構(gòu)成:

trait FileLogger extends Logger {
val out = new PrintWriter("app.log") // 構(gòu)造器的一部分
out.println("# " + new Date().toString) // 也是構(gòu)造器的一部分

def log(msg: String) { out.println(msg); out.flush() }
}

這些語(yǔ)句在任何混入了該特質(zhì)的對(duì)象在構(gòu)造時(shí)都會(huì)被執(zhí)行。 構(gòu)造器的順序:

首先調(diào)用超類的構(gòu)造器
特質(zhì)構(gòu)造器在超類構(gòu)造器之后、類構(gòu)造器之前執(zhí)行
特質(zhì)由左到右被構(gòu)造
每個(gè)特質(zhì)中,父特質(zhì)先被構(gòu)造
如果多個(gè)特質(zhì)共有一個(gè)父特質(zhì),那么那個(gè)父特質(zhì)已經(jīng)被構(gòu)造,則不會(huì)被再次構(gòu)造
所有特質(zhì)構(gòu)造完畢后,子類被構(gòu)造。 例如:
class SavingsAccount extends Account with FileLogger with ShortLogger

構(gòu)造器執(zhí)行順序:

1Account (超類)

2 Logger (第一個(gè)特質(zhì)的父特質(zhì))

3 FileLogger

4 ShortLogger

5 SavingsAccount

9 初始化特質(zhì)中的字段
特質(zhì)不能有構(gòu)造器參數(shù),每個(gè)特質(zhì)都有一個(gè)無(wú)參構(gòu)造器。這也是特質(zhì)和類的差別。 例如: 我們要在構(gòu)造的時(shí)候指定log的輸出文件:

trait FileLogger extends Logger {
val filename: String // 構(gòu)造器一部分
val out = new PrintWriter(filename) // 構(gòu)造器的一部分
def log(msg: String) { out.println(msg); out.flush() }
}

val acct = new SavingsAccount extends Account with FileLogger("myapp.log") //error,特質(zhì)沒(méi)有帶參數(shù)的構(gòu)造器

// 你也許會(huì)想到和前面重寫maxLength一樣,在這里重寫filename:
val acct = new SavingsAccount with FileLogger {
val filename = "myapp.log" // 這樣是行不通的
}

FileLogger的構(gòu)造器先于子類構(gòu)造器執(zhí)行。這里的子類其實(shí)是一個(gè)擴(kuò)展自SavingsAccount 并混入了FileLogger特質(zhì)的匿名類。而filename的初始化發(fā)生在這個(gè)匿名類中,而FileLogger的構(gòu)造器會(huì)先執(zhí)行,因此new PrintWriter(filename)語(yǔ)句會(huì)拋出一個(gè)異常。 解決方法是要么使用提前定義或者使用懶值:

val acct = new {
val filename = "myapp.log"
} with SavingsAccount with FileLogger

// 對(duì)于類同樣:
class SavingsAccount extends {
val filename = "myapp.log"
} with Account with FileLogger {
... // SavingsAccount 的實(shí)現(xiàn)
}

// 或使用lazy
trait FileLogger extends Logger {
val filename: String // 構(gòu)造器一部分
lazy val out = new PrintWriter(filename) // 構(gòu)造器的一部分
def log(msg: String) { out.println(msg); out.flush() }
}

10 擴(kuò)展類的特質(zhì)
特質(zhì)也可以擴(kuò)展類,這個(gè)類將會(huì)自動(dòng)成為所有混入該特質(zhì)的超類

trait LoggedException extends Exception with Logged {
def log() { log(getMessage()) }
}

log方法調(diào)用了從Exception超類繼承下來(lái)的getMessage 方法。那么混入該特質(zhì)的類:

class UnhappyException extends LoggedException {
override def getMessage() = "arggh!"
}

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)頁(yè)名稱:大數(shù)據(jù)Scala系列之特質(zhì)-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)鏈接:http://jinyejixie.com/article20/coijjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、服務(wù)器托管、關(guān)鍵詞優(yōu)化、動(dòng)態(tài)網(wǎng)站、網(wǎng)站收錄建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名
厦门市| 溧阳市| 舞阳县| 龙海市| 昌吉市| 武胜县| 临湘市| 临湘市| 竹溪县| 牙克石市| 沂水县| 老河口市| 济阳县| 建德市| 银川市| 潼南县| 大悟县| 秀山| 廉江市| 长治市| 涞水县| 陆丰市| 阿拉善右旗| 全南县| 剑河县| 汾西县| 修水县| 玉林市| 交城县| 招远市| 个旧市| 石屏县| 临泽县| 宁陕县| 海伦市| 沛县| 扶沟县| 衡阳县| 弋阳县| 泰顺县| 巴彦淖尔市|