Scala: Object và Companion Object
Scala
50
White

Vu Nhat Minh viết ngày 10/04/2016

Đây là bài thứ 2 trong series. Bài trước là về Class và Method. Bạn nên đọc tuần tự để hiểu tốt hơn.

Object

Trong Scala, tất cả mọi giá trị đều là một object, tất cả mọi method đều trực thuộc một object nào đó.
Khi trong Java bạn thường thấy các property và method được gán nhãn static trong một class thì trong Scala việc đó trở nên không cần thiết. Trong Scala chúng ta có thể dùng từ khóa object để định nghĩa một khoảng không gian với một tên gọi nhất định giống như là một "singleton object". Tất cả những thứ nằm trong phần không gian nói trên cũng là một object, vì vậy hoàn toàn có thể định nghĩa method và property ở trong này.

Định nghĩa hơi loằng còn nhà bà ngoằng đúng không :smile: Tóm gọn lại thì chúng ta có một cú pháp , thể hiện bằng từ khóa object

  • Có thể đặt các utility method hoặc global property trong này (giống khoảng bên trong static ở Java).
  • 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

case class Saiyan(name: String, age: Int)

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

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ẽ ko 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 đó.

Phần tiếp theo là Trait.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Vu Nhat Minh

54 bài viết.
724 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
116 29
Nếu bạn thường vào trang mua sắm của amazon, chắc sẽ chẳng lạ gì với menu Shop by Department. Tốc độ hiển thị nội dung của menu là tức thì so với d...
Vu Nhat Minh viết hơn 2 năm trước
116 29
White
87 4
Lời người dịch Người dịch là một developer , sau khi tìm đọc được bài viết này bằng bản gốc tiếng Anh đã cảm thấy như được "khai sáng" về khả năng...
Vu Nhat Minh viết hơn 2 năm trước
87 4
White
56 5
Đây là phần cuối của một series chuyên về thiết kế UI. Bạn nên đọc (Link) trước khi bắt đầu đọc phần này. Luật số 7: "Ăn trộm" như là một nghệ sỹ...
Vu Nhat Minh viết hơn 2 năm trước
56 5
Bài viết liên quan
White
10 0
Kí tự Regex cơ bản Về cơ bản thì các sử lý matching của scala.util.matching.Regex sẽ được "phó thác" (delegate) cho java Regex. Bạn có thể tạo một ...
huydx viết hơn 2 năm trước
10 0
White
7 1
Trong scala kí tự _ được dùng với khá nhiều mục đích .. không liên quan đến nhau. Tạm note lại cái đã khi nào có time sẽ quay lại viết cẩn thận sa...
huydx viết hơn 2 năm trước
7 1
White
0 0
(Bài viết hơi khó hiểu, dành cho bạn nào có hứng thú với type programming trong scala với các thư viện như shapeless chẳng hạn) Thông thường với m...
huydx viết gần 2 năm trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
54 bài viết.
724 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!