Scala: Object và Companion Object
Object trong scala là gì?
• Có thể đặt các Factory Method cho Object.
• Sử dụng như là Singleton Pattern (Cái này là một design pattern cơ bản nhé).
Ở trên thì lý do thứ 3 là có tồn tại tuy nhiên chẳng dùng bao giờ mấy, vì vậy nếu bạn vẫn lăn tăn về Singleton Pattern thì có thể bỏ qua và ko cần nhớ. Cách khai báo Object cũng không khác class là mấy.
object obj_name extends class_name with trait_name1 with trait_name2 {
}
Scala có một Object tên là Predef được định nghĩa là Import sẵn. Ví dụ hàm println() thực ra là một method của object Predef.
Sau đây mình sẽ đưa ra một ví dụ tạo object trùng tên với một class.
class Saiyan(val name: String, val age: Int)
object Saiyan {
def apply(name: String, age: Int): Saiyan = new Saiyan(name, age)
}
Apply là một hàm đặc biệt. Sau khi định nghĩa như trên thì 2 dòng dưới đây là như nhau
Saiyan.apply("goku", 100)
Saiyan("goku",100)
So với cách gọi trực tiếp new Saiyan("goku", 100) thì viết thông qua object thế này có 2 cái lợi
• Ẩn được nội dung cụ thể của class Saiyan
• Có thể trả về một instance của một subclass của Saiyan.
Cách viết như trên còn có thể viết gọn nữa như sau:
Vậy case class là gì ?
Case class
Case class là một đối tượng có 2 cách dùng. Cách dùng thứ 1 mình sẽ trình bày sau đây và cách dùng thứ 2 là trong Pattern Matching mà chúng ta sẽ gặp trong một phần khác.
Case class mang bên trong mình một class cùng tên với các Constructor Parameter đều là công khai (public). Ngoài ra mang thêm những Method cơ bản của một Object.
Thế nào là những method cơ bản của một object ?
• equals()
• hashCode()
• toString()
case class Saiyan(name: String, age: Int)
Saiyan("goku",100).equals(Saiyan("goku",100)) // true
Companion Object trong scala là gì?
Object trùng tên với class như bên trên được gọi là Companion Object. Companion Object khác biệt với Object bình thường ở chỗ: có thể truy cập ngay cả những property hay method là private.
class Saiyan(val name: String, private val age: Int)
object Saiyan {
def apply(name: String, age: Int): Saiyan = {
val s = new Saiyan(name, age)
println(s.age) // OK
return s
}
}
Nếu Object mang một cái tên khác, nó sẽ không còn được coi là Companion Object và đoạn code trên sẽ không chạy. Bạn thử sửa Object Saiyan thành Object Namek chẳng hạn xem nhé! Lưu ý là khi chạy đoạn code trên trên Scala Intepreter thì cần bật Paste mode lên (gõ :paste, paste rồi Ctrl D).
Đến đây có thể bạn sẽ nghĩ, nếu đến Private của Class mà Companion Object còn đọc được thì có gì mà Companion Object không đọc được nữa đâu ?
Câu trả lời là private[this]. Nếu gắn private[this] vào trước một Property/method thì nó sẽ chỉ được nhìn thấy duy nhất bên trong class đó.
>> Xem thêm: Scala - Lập trình hướng đối tượng và lập trình hàm