iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 22
0
Software Development

認識scala系列 第 22

Scala day 22 (Companion Object & apply & update)

  • 分享至 

  • xImage
  •  

Companion Object

如果 object 的名稱和 class 名稱相同,稱為 Companion Object (Employee).
由於 Companion Object 是要將 trait 與 object 定義在同一個檔案裡,但由於這邊是使用 REPL 做 demo,
所以再用一個 object(Emp) 把它們包起來,否則 REPL 的環境不會被視為是 Companion Object,如果是定義在一個 Employee.scala 檔案裡,則不用 Emp 包起來 :

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

scala> object Emp {
     |
     |   class Employee(val salary: Int)
     |
     |   object Employee {
     |
     |     private val emps: ListBuffer[Employee] = new ListBuffer[Employee]
     |
     |     private var sum = 0
     |
     |     def addEmp(emp:Employee) = emps += emp
     |
     |     def sumSalary = {
     |       emps.foreach(emp => sum += emp.salary)
     |       sum
     |     }
     |   }
     | }
defined object Emp

scala> Emp.Employee.addEmp(new Emp.Employee(10))
res0: scala.collection.mutable.ListBuffer[Emp.Employee] = ListBuffer(Emp$Employee@35eee641)

scala> Emp.Employee.addEmp(new Emp.Employee(20))
res1: scala.collection.mutable.ListBuffer[Emp.Employee] = ListBuffer(Emp$Employee@35eee641, Emp$Employee@4f3c7808)

scala> Emp.Employee.sumSalary
res2: Int = 30

apply function

就是將參數傳給(apply) function 的意思

scala> val sum = (num1:Int,num2:Int) => num1 + num2
sum: (Int, Int) => Int = $$Lambda$1197/530446114@3f06abd

scala> sum(2,3)
res15: Int = 5

scala> sum.apply(2,3)
res14: Int = 5

將參數傳給(apply) object

scala> object Counter {
     |  val baseNum = 10
     |  def apply(num1:Int , num2:Int) = baseNum + num1 + num2
     | }
defined object Counter

scala> Counter(2,3)
res16: Int = 15

update function

定義 :
a(x) = y 相當於 a.update(x, y),a(x,y) = x 相當於 a.update(x,y,z) 以此類推.

scala> class Cellphone {
     |
     |   val numbers = scala.collection.mutable.Map[String,(Int,Int)]()
     |
     |   def apply(name:String) = numbers(name)
     |   def update(name:String, number:(Int,Int)) = numbers(name) = number
     | }
defined class Cellphone

scala> val phonebook = new Cellphone
phonebook: Cellphone = Cellphone@1d9af731

會呼叫 Cellphone 的 update 方法 :

scala> phonebook("Daniel")=(123,45678)

scala> phonebook("Sam")=(321,876543)

會呼叫 Cellphone 的 apply 方法 :

scala> phonebook("Daniel")
res5: (Int, Int) = (123,45678)

scala> phonebook("Sam")
res6: (Int, Int) = (321,876543)

Companion Object with apply

apply 可以設計成為 factory pattern :

scala> object Trans {
     |   trait Transportation {
     |     def go
     |   }
     |   object Transportation {
     |     private class Car extends Transportation {
     |       override def go {println("drive car")}
     |     }
     |     private class Boat extends Transportation {
     |       override def go {println("drive boat")}
     |     }
     |     def apply(name:String): Transportation = {
     |       if(name == "car") {
     |         new Car
     |       } else {
     |         new Boat
     |       }
     |     }
     |   }
     | }
defined object Trans

scala> val car = Trans.Transportation("car")
car: Trans.Transportation = Trans$Transportation$Car@178cfe5e

scala> car.go
drive car

scala> val boat = Trans.Transportation("boat")
boat: Trans.Transportation = Trans$Transportation$Boat@31e90355

scala> boat.go
drive boat

總結


  • 在 scala 裡 object 可被視為 function,function 也可被視為 object,這觀念跟物件導向的觀念不太一樣,感覺 Companion Object 、apply、update 等功能也是為了要實作 functional programming.

上一篇
Scala day 21 (Set)
下一篇
Scala day 23 (implicit conversion)
系列文
認識scala30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言