Sự khác biệt giữa đối tượng trường hợp và đối tượng


226

Có sự khác biệt nào giữa trường hợp đối tượng và đối tượng trong scala không?


3
Anh ta có một điểm - không cần thiết phải có một đối tượng trường hợp để có thể tạo mẫu khớp với nó. Tôi nghĩ rằng điều này đã không được giải quyết trong câu hỏi trước ...
axel22

3
Tôi nghĩ rằng sẽ có sự khác biệt trong hành vi khớp mẫu nhưng cả đối tượng trường hợp và đối tượng bình thường đều hành xử giống nhau trong mẫu khớp với AFAIK. Thật khó để tìm thấy bất kỳ thông tin nào về các đối tượng trường hợp vì vậy tôi đang mong chờ ai đó khai sáng cho chúng tôi.
Tuổi Mooij

4
Không cần thiết phải sử dụng caseđể có mô hình phù hợp, nó chỉ là đường. Thực hiện unapplybản thân làm công việc.
Raphael

1
Câu trả lời được chấp nhận chỉ không trả lời câu hỏi, như được thảo luận trong các ý kiến ​​về nó. Cách quá muộn để tạo sự khác biệt, nhưng cần lưu ý.
itbruce

Không quá muộn để chỉnh sửa câu trả lời được chấp nhận. Việc chỉnh sửa sẽ được xem xét và nếu có liên quan, được chấp nhận.
C4stor

Câu trả lời:


111

Các lớp trường hợp khác với các lớp thông thường ở chỗ chúng nhận được:

  1. hỗ trợ khớp mẫu
  2. triển khai mặc định của equalshashCode
  3. triển khai mặc định của tuần tự hóa
  4. một triển khai mặc định đẹp hơn toString
  5. số lượng nhỏ chức năng mà họ nhận được từ tự động kế thừa từ scala.Product.

Khớp mẫu, bằng và hashCode không quan trọng lắm đối với singletons (trừ khi bạn làm điều gì đó thực sự suy biến), vì vậy bạn sẽ nhận được nhiều thứ tự, một cách hay toStringvà một số phương pháp mà bạn có thể sẽ không bao giờ sử dụng.


46
Điểm 3 và 4 của câu trả lời này là sự khác biệt chính xác giữa các đối tượng trường hợp và đối tượng. Điểm 1 và 2 không quan trọng đối với các đối tượng đơn lẻ. Và các đối tượng đơn lẻ luôn là Sản phẩm có arity 0 nên điểm 5 cũng không thành vấn đề.
Wojciech Durczyński

86
Bài đăng này tiếp tục huyền thoại objectgiống như một người độc thân. Không phải vậy. Thay vào đó, nó chính xác là những gì nó nói, một đối tượng, tức là khai báo và khởi tạo trong một. Điều này giới hạn objecttrong một trường hợp duy nhất nếu được xác định trong phạm vi gói, điều này thực sự làm cho nó trở thành một đơn lẻ, nhưng chỉ khi được định nghĩa trong PHẠM VI. Nếu được định nghĩa bên trong một lớp, bạn có thể có nhiều trường hợp như chính lớp đó (nó được khởi tạo một cách lười biếng, vì vậy nó không nhất thiết phải là 1-1). Và những đối tượng bên trong rất có thể được sử dụng làm khóa băm, làm cho mặc định bằng / hashCode rất hợp lý.
nilskp

66
Câu hỏi là về case objectlớp học, tại sao đây là câu trả lời đúng?
Ixx

10
Điều này không trả lời câu hỏi. Câu trả lời này liên quan đến sự khác biệt giữa case classvà a class. Câu hỏi là về sự khác biệt giữa case objectobject.
MK

6
@ C4stor Tuy nhiên, câu trả lời không nói lên điều đó. Một đối tượng không phải là một lớp. Cho rằng các lớp trường hợp thực hiện một số lượng ma thuật khá lớn đằng sau hậu trường, với các trường hợp và biến chứng khác nhau của Scala, không có lý do nào đơn giản để cho rằng sự khác biệt duy nhất giữa một đối tượng Scala tiêu chuẩn và một đối tượng trường hợp được giải thích bởi những gì chúng ta biết về sự khác biệt giữa các lớp tiêu chuẩn và các lớp tình huống. Câu trả lời này thậm chí không giải quyết từ ngữ của câu hỏi.
itsbruce

137

Đây là một điểm khác biệt - các đối tượng trường hợp mở rộng Serializableđặc điểm, vì vậy chúng có thể được tuần tự hóa. Các đối tượng thông thường không thể theo mặc định:

scala> object A
defined module A

scala> case object B
defined module B

scala> import java.io._
import java.io._    

scala> val bos = new ByteArrayOutputStream                                            
bos: java.io.ByteArrayOutputStream =  

scala> val oos = new ObjectOutputStream(bos)                                          
oos: java.io.ObjectOutputStream = java.io.ObjectOutputStream@e7da60                   

scala> oos.writeObject(B)

scala> oos.writeObject(A)
java.io.NotSerializableException: A$

15
Tôi nghĩ rằng đối tượng trường hợp có thể được tuần tự là sự khác biệt nhất từ đối tượng thường xuyên đặc biệt là trong giao tiếp mạng giữa diễn viên
爱国者

14
Thêm extends Serializablenên làm thủ thuật tương tự mặc dù.
nilskp

36
scala> object foo

xác định đối tượng foo

scala> case object foocase

xác định đối tượng foocase

Sự khác biệt nối tiếp:

scala> foo.asInstanceOf[Serializable]

java.lang.ClassCastException: foo $ không thể chuyển sang scala.Serializable
... 43 elided

scala> foocase.asInstanceOf[Serializable]

res1: Nối tiếp = foocase

sự khác biệt toString:

scala> foo

res2: foo.type = foo $ @ 7bf0bac8

scala> foocase

res3: foocase.type = foocase


2

các đối tượng trường hợp hoàn toàn đi kèm với việc triển khai các phương thức toString, bằng và hashCode, nhưng các đối tượng đơn giản thì không. các đối tượng trường hợp có thể được tuần tự hóa trong khi các đối tượng đơn giản không thể, điều này làm cho các đối tượng trường hợp rất hữu ích như các tin nhắn với Akka-Remote. Thêm từ khóa trường hợp trước từ khóa đối tượng làm cho đối tượng tuần tự hóa.


0

Nó tương tự với case classclass, chúng tôi chỉ sử dụng case objectthay vì case classkhi không có bất kỳ trường nào đại diện cho thông tin trạng thái bổ sung.


0

Chúng tôi biết các đối tượng và "lớp trường hợp" trước. Nhưng "case object" là sự pha trộn của cả hai, nghĩa là nó là một singleton tương tự như một đối tượng và có rất nhiều mẫu soạn sẵn như trong một lớp case. Sự khác biệt duy nhất là bản tóm tắt được thực hiện cho một đối tượng thay vì một lớp.

trường hợp đối tượng sẽ không đi kèm với những điều dưới đây:

Áp dụng, phương pháp không áp dụng. Ở đây không có phương pháp sao chép vì đây là một singleton. Không có phương pháp để so sánh bình đẳng cấu trúc. Không có nhà xây dựng là tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.