스칼라 객체의 Case Class(케이스 클래스)

View: 164 0 0
작성자: 달빛제이크
카테고리: Scala Language
발행: 2024-05-26 수정 2024-06-21

안녕하세요. 달빛제이크입니다.

지난 글에서 스칼라의 객체 지향에 대해서 설명을 드렸는데요. 이번 글에서도 객체 지향에 대한 설명을 이어가겠습니다.

4. Case Class (케이스 클래스)

Case Class는 데이터 모델링과 패턴 매칭에 최적화된 특별한 클래스 입니다.

일반 Class를 구현할 때 개발자는 완전한 객체를 구성하기 위해서 equals, hashCode, toString, accessor methods (접근자 메소드), factory methods (팩토리 메소드) 등을 직접 구현해야 하기 때문에 시간과 노력을 필요로 하고, 오류 발생 가능성을 높일 수 있는데, Case Class는 이러한 기능들을 자동으로 생성해 줍니다.

Case Class는 Class를 구현할 때 class 키워드 앞에 case 접근 제어자 (modifier)를 추가하여 간단하게 만들 수 있습니다.

// Case Class
case class Person(name: String, age: Int)

val alice = Person("Alice", 25)
println(alice.name)        // Output: Alice
println(alice.age)        // Output: 25

앞의 예제에서 Instance 객체를 생성할 때 new Keyword를 사용하지 않고 Person("Alice", 25)를 사용해서 바로 Instance를 생성한 모습을 확인할 수 있습니다.

이는 Case Class를 구현하면 Companion Object의 apply method를 자동으로 생성해주기 때문입니다.

apply method는 Companion object에 포함되어 있는 메소드로 주로 객체를 생성하거나 객체의 함수를 호출할 때 사용합니다.

apply method를 통해 객체의 인스턴스를 생성하면 new 키워드를 생략할 수 있습니다. 이러한 방식은 마치 객체를 함수처럼 호출할 수 있게 합니다.

apply method는 일반적으로 class의 생성자 또는 factory method로 사용을 하고 필요에 따라 함수 객체로도 활용할 수 있습니다.

// 기본 사용법
class person(val name: String, val age: Int)

object Person:
  def apply(name: String, age: Int): Person = new Person(name, age)

val alice = Person("Alice", 25)
println(alice.name)        // Output: Alice
println(alice.age)        // Output: 25

// 함수 객체
object Adder:
  def apply(x: Int, y: Int): Int = x + y

val sum = Adder(5,3)
println(sum)        // Output: 8

// Companion Object에서 생성자 또는 factory method로 사용
class Person(val name: String, val age: Int)

object Person:
  def apply(name: String, age: Int): Person = new Person(name, age)
  def apply(name: String): Person = new Person(name, 0)        // age 기본값을 0으로 설정

val bob = Person("Bob", 30)
val unknown  = Person("Unknown")

println(bob.name)        // Output: Bob
println(bob.age)        // Output: 30
println(unknown.name)        // Output: Unknown
println(unknown.age)        // Output: 0

예제에서 Class Parameter에 val 키워드를 추가하였는데 이것은 class field에 인수 값을 할당하기 위한 것입니다. Class Parameter에 val이나 var를 포함하지 않으면 parameter의 변수는 Instance 외부에서는 사용할 수 없습니다.

Case Class에서는 Class parameter에 val을 추가하여 immutable (불변) 변수로 설정합니다.

한 줄의 코드로 간단하게 Case Class를 작성하면 쉽게 데이터 모델링이 가능하고, Companion object의 apply method가 자동으로 생성되며, field에 대한 접근자 메소드 뿐만 아니라 Class에 필요로 하는 equals, hashCode, toString이 자동 구현되고, 패턴 매칭을 통해 데이터를 쉽게 처리할 수 있습니다.


// Data Modeling 예시
case class User(id: Int, name: String, email: String)
val user1 = User(1, "Alice", "alice@example.com")
val user2 = User(2, "Bob", "bob@example.com")

// Pattern matching
case class Address(street: String, city: String, zip: Strint)
case class Person(name: String, age: Int, address: Address)

val person = Person("Alice", 30, Address("123 Main St:, "Anytown", "12345"))
person match
  case Person(name, age, Address(street, city, zip)) => println(s"Name: $name, Age: $age, City: $city")

// Data Modeling 및 Pattern matching 활용
sealed trait Shape:
  def area: Double

case class Circle(radius: Double) extends Shape:
  def area: Double = Math.PI * radius * radius

case class Rectangle(width: Double, height: Double) extends Shape:
  def area: Double = width * height

case class Triangle(base: Double, height: Double) extends Shape:
  def area: Double = 0.5 * base * height

def printArea(shape: Shape): Unit = shape match
  case Circle(radius) => println(s"Circle area: ${shape.area}")
  case Rectangle(width, height) => println(s"Rectangle area: ${shape.area}")
  case Triangle(base, height) => println(s"Triangle area: ${shape.area}")

val shapes = List(Circle(3.0), Rectangle(4.0, 5.0), Triangle(6.0, 7.0))
shapes.foreach(printArea)

스칼라의 케이스 클래스는 개발자가 구현해야 하는 기능들을 자동으로 생성해 주기 때문에 데이터 중심의 애플리케이션을 보다 쉽게 작성할 수 있도록 도와줍니다.

또한 케이스 클래스를 적절히 활용하면 코드의 가독성과 유지 보수성을 크게 향상 시킬 수 있습니다.

지금까지 스칼라의 객체 지향 프로그래밍에 대해 알아 보았습니다.

스칼라 언어에서 객체 지향 프로그램의 역할은 프로그래밍 구조를 담당하면서 코드의 구조를 명확하게 하고, 코드의 재사용성을 높이며,유지 보수를 용이하게 하기 위한 것입니다.

실제로 클래스를 구현하기 위해서는 Package, Imports, Exports, Access modifiers(접근 제어자), Primary Constructor(기본 생성자), Auxiliary Constructor(보조 생성자), name space, final 키워드, 필드 초기화 등 세부적인 항목들에 대해서도 알아야 하지만 그 쓰임새 및 문법 규칙이 어렵지 않아서 쉽게 이해할 수 있을 것입니다.

다음 글에서는 객체 지향과 타입 시스템에 같이 연관되어 있는 스칼라의 Class hierarchy (클래스 계층 구조) 에 대해 간단하게 살펴보겠습니다.

감사합니다.

comments 0