스칼라는 케이스 클래스 개념을 지원하는데 특징은 아래와 같다.
- 불변
- 패턴매칭을 통해 분해가능
- 레퍼런스가 아닌 구조적인 동등성으로 비교
- 초기화와 운영이 간결
예제
Notification.scala이라는 case class스칼라 파일을 생성
abstract class Notification
case class Email(sourceEmail: String, title: String, body: String) extends Notifica
case class SMS(sourceNumber: String, message: String) extends Notification
case class VoiceRecording(contactName: String, link: String) extends Notification
클래스 Email, SMS, VoiceRecording은 일반적인 클래스와 다르다.
1.
인스턴스를 생성할 때 NEW 키워드 생략가능.
Ex)
val emailFromJohn = Email("doe@mail.com", "Greetings!", "Hello World!")
2.
생성자 파라미터들에 대한 getter함수가 자동으로 정의.
public값으로 다뤄지며 직접 접근가능
Ex)
val title = emailFromJohn.title
println(title)
3.
케이스클래스 필드 수정 불가능
Ex)
emailFromJohn.title = "Goodbye From John!"
모든 케이스 클래스 필드는 기본적으로 val이다.
// var을 사용하여 변경할 수 있지만, 권장하지 않는다.
4.
클래스 복사가 가능하며 필드값을 대체할 수도 있다.
Ex)
val editedEmail =
emailFromJohn.copy(title = "I am learning Scala!", body = "It's so cool!")
println(emailFromJohn)
// prints "Email(john.doe@mail.com,Greetings From John!,Hello World)"
println(editedEmail)
5.
모든 케이스클래스에 대해 equals 메서드와 toString메서드를 생성
Ex)
val firstSms = SMS("12345", "Hello!")
val secondSms = SMS("12345", "Hello!")
if (firstSms == secondSms) {
println("They are equal!")
}
println("SMS is: " + firstSms)
6.
케이스클래스를 통해 데이터와 함께 동작하는 패턴매칭 사용가능
object Test {
def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
"You got an email from " + email + " with title: " + title
case SMS(number, message) =>
"You got an SMS from " + number + "! Message: " + message
case VoiceRecording(name, link) =>
"you received a Voice Recording from " + name + "! Click the link to hear it: " + link
}
}
def main(args: Array[String]): Unit = {
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
println(showNotification(someSms))
println(showNotification(someVoiceRecording))
}
}
7.
패턴매칭 if를 통한 다른 예제
object Test {
def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
"You got an email from " + email + " with title: " + title
case SMS(number, message) =>
"You got an SMS from " + number + "! Message: " + message
case VoiceRecording(name, link) =>
"you received a Voice Recording from " + name + "! Click the link to hear it: " + link
}
}
def showNotificationSpecial(notification: Notification, specialEmail: String, specialNumber: String): String = {
notification match {
case Email(email, _, _) if email == specialEmail =>
"You got an email from special someone!"
case SMS(number, _) if number == specialNumber =>
"You got an SMS from special someone!"
case other =>
showNotification(other) // nothing special, delegate to our original showNotification function
}
}
def main(args: Array[String]): Unit = {
val SPECIAL_NUMBER = "55555"
val SPECIAL_EMAIL = "jane@mail.com"
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
val specialEmail = Email("jane@mail.com", "Drinks tonight?", "I'm free after 5!")
val specialSms = SMS("55555", "I'm here! Where are you?")
println(showNotificationSpecial(someSms, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(someVoiceRecording, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(specialEmail, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(specialSms, SPECIAL_EMAIL, SPECIAL_NUMBER))
}
}
참조 :
https://docs.scala-lang.org/ko/tutorials/scala-for-java-programmers.html
https://docs.scala-lang.org/ko/tour/case-classes.html