日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Scala講座:類(lèi)定義和構(gòu)造函數(shù)

本文節(jié)選自最近在日本十分流行的Scala講座系列的第三篇,由JavaEye的fineqtbull翻譯。本系列的作者牛尾剛在日本寫(xiě)過(guò)不少有關(guān)Java和Ruby的書(shū)籍,相當(dāng)受歡迎。

專(zhuān)注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)永興免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千余家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

序言

到這為止牛尾先生作了一下Scala語(yǔ)言的介紹,接下來(lái)以微型旅游的形式做一下有關(guān)Scala語(yǔ)法特點(diǎn)的探險(xiǎn)。如果是初次接觸的讀者可以大略的讀一下第一和第二回的講座,就可以順暢地讀懂本文了。

這次旅行準(zhǔn)備訪(fǎng)問(wèn)的是,類(lèi)定義和構(gòu)造函數(shù);混合Scala與Java程序以及與Java語(yǔ)言在語(yǔ)法上的差別;稱(chēng)為特征(Trait)的mixin型多重繼承;函數(shù)定義和函數(shù)式編程;類(lèi)型層次和集合;模式匹配;XML文本操作;等主題。

首先,作為復(fù)習(xí)我們先整理一下Scala語(yǔ)言的要點(diǎn)。

? 事實(shí)1:Scala中可以簡(jiǎn)單使用所有Java類(lèi),Java中也可以自由調(diào)用Scala類(lèi)。Scala類(lèi)還可以定義為Java類(lèi)的子類(lèi)。也就是說(shuō),龐大的已有Java、J2EE、Java ME和CLDC資源可以被更有效和合理地應(yīng)用了。(在Net上,雖然現(xiàn)在的版本還不支持,1.x版曾經(jīng)支持過(guò),將來(lái)也有復(fù)活的計(jì)劃)

? 事實(shí)2:Scala在JVM上被執(zhí)行,編譯后的代碼執(zhí)行性能基本與Java代碼不相上下。結(jié)果是比大多數(shù)腳本語(yǔ)言的速度都快一位數(shù)以上。

? 事實(shí)3:Scala一方面是純面向?qū)ο蟮恼Z(yǔ)言,另一方面在這框架中提供了完全的函數(shù)式編程的功能。Scala的所有數(shù)據(jù)都是對(duì)象,函數(shù)也是對(duì)象,可以作為數(shù)據(jù)來(lái)操作。

? 事實(shí)4:Scala在對(duì)于開(kāi)發(fā)Javac和Java Generics有貢獻(xiàn)的Martin Ordersky教授所率領(lǐng)的強(qiáng)大的開(kāi)放體制下被開(kāi)發(fā),不是實(shí)驗(yàn)室的實(shí)驗(yàn)品,而是將來(lái)可以期待的通用編程語(yǔ)言。Scala發(fā)布的頻率非???,文檔也很豐富,現(xiàn)在的版本是Scala2.7.1 final(2008/8)。

類(lèi)定義和構(gòu)造函數(shù)

那么,定義一下類(lèi)吧。首先定義一下在語(yǔ)言介紹中一直用到的Person類(lèi)。首先是Java類(lèi)

 
 
 
  1. public class Person  
  2. {  
  3. private String lastName; //姓  
  4. private String firstName; //名  
  5. private Person spouse; //配偶的Person對(duì)象  
  6. public Person(String fn, String ln, Person s)  
  7. {  
  8. lastName = ln; firstName = fn; spouse = s;  
  9. }  
  10. public Person(String fn, String ln)  
  11. {  
  12. this(fn, ln, null); //未婚時(shí)沒(méi)有配偶  
  13. }  
  14. public String getFirstName()  
  15. {  
  16. return firstName;  
  17. }  
  18. public String getLastName()  
  19. {  
  20. return lastName;  
  21. }  
  22. public Person getSpouse()  
  23. {  
  24. return spouse;  
  25. }  
  26. public void setSpouse(Person p)  
  27. {  
  28. spouse = p;  
  29. //沒(méi)有考慮婚姻對(duì)姓和名的影響  
  30. }  
  31. public String introduction()  
  32. {  
  33. return "我的名字是," + firstName + " " + lastName +  
  34. (spouse != null ?  
  35. " 對(duì)方的名字是," + spouse.firstName + " " + spouse.lastName + " 。" :  
  36. " 。");  
  37. }  
  38. }  

下面是用Scala寫(xiě)的同樣內(nèi)容

 
 
 
  1. class Person(fn : String, ln : String, s : Person)  
  2. {  
  3. val lastName = ln; //沒(méi)有private修飾符則認(rèn)為是public  
  4. val firstName = fn; //從構(gòu)造函數(shù)的參數(shù)類(lèi)型推斷為String  
  5. var spouse = s; //從構(gòu)造函數(shù)的參數(shù)類(lèi)型推斷為Person  
  6. def this(fn : String, ln : String) = { this(fn, ln, null); }  
  7. def introduction() : String =  
  8. return "我的名字是, " + lastName + " " + firstName +  
  9. (if (spouse != null) " 對(duì)方的名字是, " + spouse.lastName + " " + spouse.firstName + "。" else "。");  
  10. }  

從行數(shù)來(lái)看大概縮短為1/3,代碼變得非常簡(jiǎn)潔了。用val來(lái)定義常量,var來(lái)定義可再賦值的實(shí)例屬性。用def來(lái)定義方法。Scala的目的之一就是使書(shū)寫(xiě)的代碼更簡(jiǎn)潔易讀。

在Scala中實(shí)例屬性默認(rèn)為public,可以用該實(shí)例屬性名來(lái)直接存取屬性的值。

 
 
 
  1. scala> val p0 = new Person("Fei", "Zhang")  
  2. p0: Person = Person@6e9b6a 
  3. scala> p0.introduction  
  4. res1: String = 我的名字是, Zhang Fei。  

而且Scala對(duì)于調(diào)用方法的“.”符號(hào),在不發(fā)生歧義的情況下可以替換為空格。但是,這里不能加上空的參數(shù)表()。

 
 
 
  1. scala> p0 firstName //同p0.firstName等同  
  2. res3: String = Fei  
  3. scala> p0 spouse //現(xiàn)在未婚,所以spouse的值為null  
  4. res4: Person = null 
  5. scala> p0.spouse() //注意,Scala中.m和.m()的含義不同  
  6. : 6: error: p0.spouse of type Person does not take parameters  
  7. p0.spouse() 

接下來(lái)那讓ZhangFei結(jié)婚吧。先準(zhǔn)備好女方DiaoChan對(duì)象,然后把她設(shè)置到p0的spouse屬性。這時(shí)構(gòu)造函數(shù)第三個(gè)參數(shù)為配偶,所以賦予p0。

為了防止誤解先說(shuō)明一下,p0最初是用val來(lái)定義的所以是不可再賦值的,不過(guò)改變p0所指對(duì)象的內(nèi)部狀態(tài)還是可以的。因此,如下所示結(jié)婚后還可以讓他再婚。

 
 
 
  1. scala> p0 spouse = new Person("Chan", "Diao", p0) //DiaoChan和ZhangFei結(jié)婚  
  2. scala> (p0 spouse) firstName //寫(xiě)成p0 spouse firstName就會(huì)出錯(cuò)  
  3. res6: String = Chan  
  4. scala> p0 spouse = null //ZhangFei離婚  
  5. scala> p0 spouse = new Person("Shi", "Xi", p0) //和XiShi再婚  

定義Scala的類(lèi)比較有趣的是定義基本(primary)構(gòu)造函數(shù)時(shí)在類(lèi)名稱(chēng)后直接加上構(gòu)造函數(shù)的參數(shù)表。基本構(gòu)造函數(shù)參數(shù)的類(lèi)型不可省略(包括模式匹配,這是對(duì)象的類(lèi)型信息的基礎(chǔ),不能省略也是當(dāng)然的)。另一方面,可以注意到類(lèi)型定義中的變量定義沒(méi)有指定類(lèi)型,這都是靠從構(gòu)造函數(shù)參數(shù)的類(lèi)型推斷出來(lái)的。

而且聲明為def this(ln:String, fn:String)的派生構(gòu)造函數(shù)也是從基本構(gòu)造函數(shù)而來(lái)的。函數(shù)體內(nèi)通過(guò)調(diào)用this(ln, fn, null),給基本構(gòu)造函數(shù)的第三個(gè)參數(shù)賦予null來(lái)實(shí)現(xiàn)為了未婚人士準(zhǔn)備的只有兩個(gè)參數(shù)的構(gòu)造函數(shù)。

這個(gè)類(lèi)定義還可以縮短如下

 
 
 
  1. class Person(val firstName:String, val lastName:String, var spouse:Person) {  
  2. def this(fn:String, ln:String) = this(fn, ln, null)  
  3. def introduction = "我的名字是," + lastName + " " + firstName +  
  4. (if (spouse != null) ",對(duì)方的名字是," + spouse.lastName + " " + spouse.firstName + "。" else "。")  
  5. }  

由于在類(lèi)中基本構(gòu)造函數(shù)的參數(shù)定義前加上val或var后,對(duì)應(yīng)的實(shí)例屬性就會(huì)被定義,所以原來(lái)的屬性定義就不需要了。而且,編譯器會(huì)自動(dòng)追加用于存取這些屬性的方法。Scala中基本上可以去除語(yǔ)句尾部的“;”符號(hào),這里也都去除了。

 
 
 
  1. scala> val p1 = new Person("Yu", "Guan", new Person("ZheTian", "Wu"))  
  2. p1: Person = Person@904f75 
  3. scala> p1.lastName  
  4. res7: String = Guan  
  5. scala> p1.spouse  
  6. res8: Person = Person@2e879 

上述程序中描述對(duì)象的字符串比較難解,下面就擴(kuò)展一下類(lèi)使他顯示姓和名吧。任何對(duì)象的文字描述是由對(duì)象的最根類(lèi)Any的toString:String方法來(lái)實(shí)現(xiàn)的。在各個(gè)類(lèi)中使用自己的實(shí)現(xiàn)來(lái)覆蓋這個(gè)方法就可以了,這里的顯示格式為[姓:firstName 名:lastName 配偶:沒(méi)有或(姓:firstName 名:lastName)]。另外,Scala中覆蓋父類(lèi)的方法一定要加上override修飾符。

 
 
 
  1. class Person ... { ...  
  2. override def toString : String = super.toString + " [姓: " + lastName + " 名: " + firstName + " 配偶: " + (if (spouse != null) " ("+ spouse.lastName + "," + spouse.firstName + ")" else "沒(méi)有") + "]" 
  3. ...} 

下面是修改后的效果

 
 
 
  1. scala> val p1 = new Person("Yu", "Guan", new Person("ZheTian", "Wu"))  
  2. p1: Person = Person@4a0ac5 [姓: Guan 名: Yu 配偶: (Wu, ZheTian)]  
  3. scala> p1  
  4. res0: Person = Person@4a0ac5 [姓: Guan 名: Yu 配偶: (Wu, ZheTian)] 

Scala講座中類(lèi)定義和構(gòu)造函數(shù)的內(nèi)容就到這里。

【編輯推薦】

  1. Scala講座:面向?qū)ο蠛秃瘮?shù)式的特點(diǎn)總結(jié)
  2. Scala講座:函數(shù)式編程處理樹(shù)結(jié)構(gòu)數(shù)據(jù)
  3. Scala講座:編程的思考方法
  4. Scala講座:將函數(shù)作為第一類(lèi)對(duì)象來(lái)處理
  5. Scala講座:全局變量問(wèn)題的解決

名稱(chēng)欄目:Scala講座:類(lèi)定義和構(gòu)造函數(shù)
分享URL:http://www.dlmjj.cn/article/dposgch.html