Scala類和物件


本章將介紹如何在Scala程式設計中使用類和物件。類是物件的藍圖(或叫模板)。定義一個類後,可以使用關鍵字new來建立一個類的物件。 通過物件可以使用定義的類的所有功能。

下面的圖通過一個包含成員變數(namerollNo)和成員方法(setName()setRollNo())的Student類的例子來演示類和物件。最後都是類的成員。類是一個模板的東西,而物件是真實存在的。 在下圖中,Student是一個類,而具體學生:Harini, John, 和 Maria 是學生類的物件,這此物件有是名字和註冊號。

類基礎

以下是在Scala中定義類的簡單語法。這個類定義了兩個變數xy以及一個move方法,它沒有返回值。

使用類的名稱作為一個類建構函式,建構函式可以使用多個引數。 上面的程式碼定義了兩個建構函式引數xcyc; 它們在類的整個定義中都是可見的。

語法

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("Point x location : " + x);
      println ("Point y location : " + y);
   }
}

如本章前面所述,您可以使用關鍵字new來建立物件,然後存取類欄位和方法,如下例所示:

import java.io._

class Point(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 ("Point x location : " + x);
      println ("Point y location : " + y);
   }
}

object Demo {
   def main(args: Array[String]) {
      val pt = new Point(10, 20);

      // Move to a new location
      pt.move(10, 10);
   }
}

將上述程式儲存在Demo.scala中,並使用以下命令編譯和執行此程式。

D:\software\scala-2.12.3\bin>scalac Demo.scala

D:\software\scala-2.12.3\bin>scala Demo
Point x location : 20
Point y location : 30

D:\software\scala-2.12.3\bin>

擴充套件類

在Scala中,我們可以擴充套件一個Scala類,使用與Java中相同的方式設計繼承的類(使用extends關鍵字),但有兩個限制:方法重寫需要override關鍵字,只有主建構函式可以通過引數呼叫基礎類別建構函式。讓我們擴充套件上面的類,並增加一個類的方法。

例子

讓我們使用兩個類Point作為一個例子(與上面一樣)和Location類,Location類是一個使用extends關鍵字建立的繼承類。 這樣的「擴充套件」子句有兩個效果:它使得Location類從Point類繼承所有非私有成員,並且使型別Location成為Point類型別的子型別。 所以Point類被稱為超類(父類別),Location類被稱為子類。擴充套件一個類並繼承父類別的所有功能稱為繼承,但Scala允許只從一個類繼承(不支援多繼承)。

注意 - 在Point類中的move()方法和Location類中的move()方法不會覆蓋move的相應定義,因為它們是不同的定義(例如,前者採用兩個引數,後者採用三個引數)。

參考以下範例程式來實現繼承 -

import java.io._

class Point(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 ("Point x location : " + x);
      println ("Point y location : " + y);
   }
}

class Location(override val xc: Int, override val yc: Int,
   val zc :Int) extends Point(xc, yc){
   var z: Int = zc

   def move(dx: Int, dy: Int, dz: Int) {
      x = x + dx
      y = y + dy
      z = z + dz
      println ("Point x location : " + x);
      println ("Point y location : " + y);
      println ("Point z location : " + z);
   }
}

object Demo {
   def main(args: Array[String]) {
      val loc = new Location(10, 20, 15);

      // Move to a new location
      loc.move(10, 10, 5);
   }
}

將上述程式儲存在原始檔:Demo.scala中,並使用以下命令編譯和執行此程式,輸出結果如下 -

D:\software\scala-2.12.3\bin>scalac Demo.scala

D:\software\scala-2.12.3\bin>scala Demo
Point x location : 20
Point y location : 30
Point z location : 20

D:\software\scala-2.12.3\bin>

隱性類

當類在範圍內時,隱式類允許與類的主建構函式進行隱式對話。隱式類是一個標有'implicit'關鍵字的類。此功能在Scala 2.10中引入。

語法 - 以下是隱式類的語法。這裡,隱式類始終位於物件範圍內,所有方法定義都被允許,因為隱式類不能是頂級類。

語法

object <object name> {
   implicit class <class name>(<Variable>: Data type) {
      def <method>(): Unit =
   }
}

例子

下面演示如何使用隱式類,建立一個名稱為IntTimes的隱式類,並定義一個times()方法。times()包含一個迴圈事務,它將按給定的次數執行語句。假設要執行4println(「」Hello「)語句。

以下是範例程式程式碼。在這個例子中,使用了兩個物件類(RunDemo),將這兩個類儲存在不同的檔案中,名稱如下 -

Run.scala - 將以下程式儲存在原始檔:Run.scala

object Run {
   implicit class IntTimes(x: Int) {
      def times [A](f: =>A): Unit = {
         def loop(current: Int): Unit =

         if(current > 0){
            f
            loop(current - 1)
         }
         loop(x)
      }
   }
}

Demo.scala - 將以下程式儲存在原始檔:Demo.scala 中 -

import Run._

object Demo {
   def main(args: Array[String]) {
      4 times println("hello")
   }
}

用於以下命令編譯和執行這兩個程式,輸出結果如下 -

D:\software\scala-2.12.3\bin>scalac Demo.scala

D:\software\scala-2.12.3\bin>scala Demo
hello
hello
hello
hello

D:\software\scala-2.12.3\bin>

-

  • 隱式類必須在另一個類/物件/特徵中定義(不在頂層)。
  • 隱式類在其建構函式中只能使用一個非預設引數。
  • 隱式類作用域中不可以具有與隱式類相同名稱的的任何方法,成員或物件。

單例物件

Scala比Java更物件導向,因為在Scala中不能擁有靜態成員,Scala它使用單例物件。單例是一種只能有一個範例的物件。使用object關鍵字物件而不是類關鍵字建立單例。由於無法範例化單例物件,因此無法將引數傳遞給主建構函式。下面列出Scala使用單例物件的所有範例。

以下是實現單例的範例程式 -

import java.io._

class Point(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 Demo {
   def main(args: Array[String]) {
      val point = new Point(10, 20)
      printPoint

      def printPoint{
         println ("Point x location : " + point.x);
         println ("Point y location : " + point.y);
      }
   }
}

將上述程式儲存在原始檔:Demo.scala 中,使用以下命令編譯和執行此程式,輸出結果如下 -

D:\software\scala-2.12.3\bin>scalac Demo.scala

D:\software\scala-2.12.3\bin>scala Demo
Point x location : 10
Point y location : 20