Scala基础教程(七):类和对象、特征
擴展一個類:
可以擴展scala類以類似的方式,如在Java中的一樣,但有兩個限制:方法重載需要override關鍵字,只有主構造可以傳遞參數給基構造。現在擴展上面的類,并增加一個類的方法:
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類被稱為子類。擴展一個類,繼承父類的所有功能,被稱為繼承,但 scala允許繼承,只能從一個唯一的類。讓我們看看完整的例子,顯示繼承的用法:
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,不會覆蓋?move 方法相應的定義,因為它們是不同的定義(例如,前兩個參數,而后者則需要三個參數)。
讓我們編譯和運行上面的程序,這將產生以下結果:
單例對象:
Scala比Java更面向對象,因為在Scala中不能有靜態成員。相反,Scala有單例的對象。單例就是只能有一個實例,即,類的對象。可以使用關鍵字object代替class關鍵字,而不是創建單例。因為不能實例化一個單獨的對象,不能將參數傳遞給主構造。前面已經看到全部采用單一對象,調用 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); ????? } ?? } }當上述代碼被編譯和執行時,它產生了以下結果:
C:/>scalac Test.scala C:/>scala Test Yiibai x location : 10 Yiibai y location : 20 ? C:/>特性封裝方法和字段定義,然后可以通過將它們混合成類被重用。不同于類繼承,其中每個類都必須繼承只有一個父類,一類可以在任意數量特質混合。
特征用于通過指定支持的方法的簽名定義的對象類型。Scala中也允許部分實現特性但可能不具有構造參數。
一個特征定義看起來就像不同的是它使用關鍵字trait如下類定義:
trait Equal { ? def isEqual(x: Any): Boolean ? def isNotEqual(x: Any): Boolean = !isEqual(x) }這種特質由兩個方法的isEqual和isNotEqual。這里,我們沒有給出任何實現的isEqual其中作為另一種方法有它的實現。擴展特性的子類可以給實施未實現的方法。因此,一個特點是非常相似Java的抽象類。下面是一個完整的例子來說明特性的概念:
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)) ?? } }當上述代碼被編譯和執行時,它產生了以下結果:
C:/>scalac Test.scala C:/>scala Test false true true ? C:/>什么時候使用特性?
沒有嚴格的規定,但這里有一些指導原則需要考慮:
·????????如果行為不被重用,則要使它成為一個具體的類。它畢竟不是可重復使用的行為。
·????????如果它可能在多個不相關的類被重用,使它成為一個性狀。只有特性可混入的類層次結構的不同部分。
·????????如果想它從繼承Java代碼,使用抽象類。
·????????如果打算在已編譯的形式分發,而且希望外部組織編寫的類繼承它,可能會傾向于使用抽象類。
·????????如果效率是非常重要的,傾向于使用類。
?
?
模式匹配是Scala中第二個最廣泛使用的功能,經過函數值和閉包。Scala中大力支持模式匹配處理消息。
模式匹配包括替代的序列,每個開始使用關鍵字case。每個備選中包括模式和一個或多個表達式,如果模式匹配將被計算。一個箭頭符號=>分開的表達模式。這里是一個小例子,它展示了如何匹配一個整數值:
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" ?? } }當上述代碼被編譯和執行時,它產生了以下結果:
C:/>scalac Test.scala C:/>scala Test many ? C:/>使用case語句塊定義一個函數,該函數映射整數字符串。匹配關鍵字提供應用函數(如模式匹配函數以上)為一個對象的一個方便的方法。下面是第二個示例,它匹配針對不同類型的模式值:
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" ?? } }當上述代碼被編譯和執行時,它產生了以下結果:
C:/>scalac Test.scala C:/>scala Test 2 many one ? C:/>第一個case ,如果 x 指的是整數值1. 如果x等于字符串“2”的第二case相匹配匹配。第三種case 是由一個輸入模式;它匹配針對任何整數,并結合選擇值xto整數類型的變量y。以下為文字相同的匹配... case 表達式用括號 {...} 另一種形式:
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
總結
以上是生活随笔為你收集整理的Scala基础教程(七):类和对象、特征的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scala基础教程(六):字符串、数组、
- 下一篇: Scala基础教程(八):模式匹配、正则