Scala基础教程(七):类和对象、特征
擴(kuò)展一個(gè)類:
可以擴(kuò)展scala類以類似的方式,如在Java中的一樣,但有兩個(gè)限制:方法重載需要override關(guān)鍵字,只有主構(gòu)造可以傳遞參數(shù)給基構(gòu)造。現(xiàn)在擴(kuò)展上面的類,并增加一個(gè)類的方法:
class Yiibai(val xc: Int, val yc: Int) { ?? var x: Int = xc ?? var y: Int = yc ?? def move(dx: Int, dy: Int) { ????? x = x + dx ????? y = y + dy ????? println ("Yiibai x location : " + x); ????? println ("Yiibai y location : " + y); ?? } } ? class Location(override val xc: Int, override val yc: Int, ?? val zc :Int) extends Yiibai(xc, yc){ ?? var z: Int = zc ? ?? def move(dx: Int, dy: Int, dz: Int) { ????? x = x + dx ????? y = y + dy ????? z = z + dz ????? println ("Yiibai x location : " + x); ????? println ("Yiibai y location : " + y); ????? println ("Yiibai z location : " + z); ?? } }extends子句有兩種作用:它使類Location繼承類Yiibai所有非私有成員,它使Location類 作為Yiibai類的子類。?因此,這里的Yiibai類稱為超類,而Location類被稱為子類。擴(kuò)展一個(gè)類,繼承父類的所有功能,被稱為繼承,但 scala允許繼承,只能從一個(gè)唯一的類。讓我們看看完整的例子,顯示繼承的用法:
import java.io._ ? class Yiibai(val xc: Int, val yc: Int) { ?? var x: Int = xc ?? var y: Int = yc ?? def move(dx: Int, dy: Int) { ????? x = x + dx ????? y = y + dy ????? println ("Yiibai x location : " + x); ????? println ("Yiibai y location : " + y); ?? } } ? class Location(override val xc: Int, override val yc: Int, ?? val zc :Int) extends Yiibai(xc, yc){ ?? var z: Int = zc ? ?? def move(dx: Int, dy: Int, dz: Int) { ????? x = x + dx ????? y = y + dy ????? z = z + dz ????? println ("Yiibai x location : " + x); ????? println ("Yiibai y location : " + y); ????? println ("Yiibai z location : " + z); ?? } } ? object Test { ?? def main(args: Array[String]) { ????? val loc = new Location(10, 20, 15); ? ????? // Move to a new location ????? loc.move(10, 10, 5); ?? } }需要注意的是方法move,不會(huì)覆蓋?move 方法相應(yīng)的定義,因?yàn)樗鼈兪遣煌亩x(例如,前兩個(gè)參數(shù),而后者則需要三個(gè)參數(shù))。
讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:
單例對象:
Scala比Java更面向?qū)ο?#xff0c;因?yàn)樵赟cala中不能有靜態(tài)成員。相反,Scala有單例的對象。單例就是只能有一個(gè)實(shí)例,即,類的對象。可以使用關(guān)鍵字object代替class關(guān)鍵字,而不是創(chuàng)建單例。因?yàn)椴荒軐?shí)例化一個(gè)單獨(dú)的對象,不能將參數(shù)傳遞給主構(gòu)造。前面已經(jīng)看到全部采用單一對象,調(diào)用 Scala的main方法的例子。以下是單例顯示的相同的例子:
import java.io._ ? class Yiibai(val xc: Int, val yc: Int) { ?? var x: Int = xc ?? var y: Int = yc ?? def move(dx: Int, dy: Int) { ????? x = x + dx ????? y = y + dy ?? } } ? object Test { ?? def main(args: Array[String]) { ????? val yiibai = new Yiibai(10, 20) ????? printYiibai ? ????? def printYiibai{ ???????? println ("Yiibai x location : " + yiibai.x); ???????? println ("Yiibai y location : " + yiibai.y); ????? } ?? } }當(dāng)上述代碼被編譯和執(zhí)行時(shí),它產(chǎn)生了以下結(jié)果:
C:/>scalac Test.scala C:/>scala Test Yiibai x location : 10 Yiibai y location : 20 ? C:/>特性封裝方法和字段定義,然后可以通過將它們混合成類被重用。不同于類繼承,其中每個(gè)類都必須繼承只有一個(gè)父類,一類可以在任意數(shù)量特質(zhì)混合。
特征用于通過指定支持的方法的簽名定義的對象類型。Scala中也允許部分實(shí)現(xiàn)特性但可能不具有構(gòu)造參數(shù)。
一個(gè)特征定義看起來就像不同的是它使用關(guān)鍵字trait如下類定義:
trait Equal { ? def isEqual(x: Any): Boolean ? def isNotEqual(x: Any): Boolean = !isEqual(x) }這種特質(zhì)由兩個(gè)方法的isEqual和isNotEqual。這里,我們沒有給出任何實(shí)現(xiàn)的isEqual其中作為另一種方法有它的實(shí)現(xiàn)。擴(kuò)展特性的子類可以給實(shí)施未實(shí)現(xiàn)的方法。因此,一個(gè)特點(diǎn)是非常相似Java的抽象類。下面是一個(gè)完整的例子來說明特性的概念:
trait Equal { ? def isEqual(x: Any): Boolean ? def isNotEqual(x: Any): Boolean = !isEqual(x) } ? class Yiibai(xc: Int, yc: Int) extends Equal { ? var x: Int = xc ? var y: Int = yc ? def isEqual(obj: Any) = ??? obj.isInstanceOf[Yiibai] && ??? obj.asInstanceOf[Yiibai].x == x } ? object Test { ?? def main(args: Array[String]) { ????? val p1 = new Yiibai(2, 3) ????? val p2 = new Yiibai(2, 4) ????? val p3 = new Yiibai(3, 3) ? ????? println(p1.isNotEqual(p2)) ????? println(p1.isNotEqual(p3)) ????? println(p1.isNotEqual(2)) ?? } }當(dāng)上述代碼被編譯和執(zhí)行時(shí),它產(chǎn)生了以下結(jié)果:
C:/>scalac Test.scala C:/>scala Test false true true ? C:/>什么時(shí)候使用特性?
沒有嚴(yán)格的規(guī)定,但這里有一些指導(dǎo)原則需要考慮:
·????????如果行為不被重用,則要使它成為一個(gè)具體的類。它畢竟不是可重復(fù)使用的行為。
·????????如果它可能在多個(gè)不相關(guān)的類被重用,使它成為一個(gè)性狀。只有特性可混入的類層次結(jié)構(gòu)的不同部分。
·????????如果想它從繼承Java代碼,使用抽象類。
·????????如果打算在已編譯的形式分發(fā),而且希望外部組織編寫的類繼承它,可能會(huì)傾向于使用抽象類。
·????????如果效率是非常重要的,傾向于使用類。
?
?
模式匹配是Scala中第二個(gè)最廣泛使用的功能,經(jīng)過函數(shù)值和閉包。Scala中大力支持模式匹配處理消息。
模式匹配包括替代的序列,每個(gè)開始使用關(guān)鍵字case。每個(gè)備選中包括模式和一個(gè)或多個(gè)表達(dá)式,如果模式匹配將被計(jì)算。一個(gè)箭頭符號=>分開的表達(dá)模式。這里是一個(gè)小例子,它展示了如何匹配一個(gè)整數(shù)值:
object Test { ?? def main(args: Array[String]) { ????? println(matchTest(3)) ? ?? } ?? def matchTest(x: Int): String = x match { ????? case 1 => "one" ????? case 2 => "two" ????? case _ => "many" ?? } }當(dāng)上述代碼被編譯和執(zhí)行時(shí),它產(chǎn)生了以下結(jié)果:
C:/>scalac Test.scala C:/>scala Test many ? C:/>使用case語句塊定義一個(gè)函數(shù),該函數(shù)映射整數(shù)字符串。匹配關(guān)鍵字提供應(yīng)用函數(shù)(如模式匹配函數(shù)以上)為一個(gè)對象的一個(gè)方便的方法。下面是第二個(gè)示例,它匹配針對不同類型的模式值:
object Test { ?? def main(args: Array[String]) { ????? println(matchTest("two")) ????? println(matchTest("test")) ????? println(matchTest(1)) ? ?? } ?? def matchTest(x: Any): Any = x match { ????? case 1 => "one" ????? case "two" => 2 ????? case y: Int => "scala.Int" ????? case _ => "many" ?? } }當(dāng)上述代碼被編譯和執(zhí)行時(shí),它產(chǎn)生了以下結(jié)果:
C:/>scalac Test.scala C:/>scala Test 2 many one ? C:/>第一個(gè)case ,如果 x 指的是整數(shù)值1. 如果x等于字符串“2”的第二case相匹配匹配。第三種case 是由一個(gè)輸入模式;它匹配針對任何整數(shù),并結(jié)合選擇值xto整數(shù)類型的變量y。以下為文字相同的匹配... case 表達(dá)式用括號 {...} 另一種形式:
object Test { ?? def main(args: Array[String]) { ????? println(matchTest("two")) ????? println(matchTest("test")) ????? println(matchTest(1)) ? ?? } ?? def matchTest(x: Any){ ????? x match { ???????? case 1 => "one" ???????? case "two" => 2 ???????? case y: Int => "scala.Int" ???????? case _ => "many" ????? } ?? } }
from: http://www.yiibai.com/scala/scala_basic_syntax.html
總結(jié)
以上是生活随笔為你收集整理的Scala基础教程(七):类和对象、特征的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scala基础教程(六):字符串、数组、
- 下一篇: Scala基础教程(八):模式匹配、正则