Scala 언어에서 case class에 final을 왜 붙히는 걸까?
View: 124
0
0
작성자: 코딩!제이크
카테고리: Scala Language
발행: 2024-10-01
수정
2024-10-01
Scala의 case class는 굉장히 유용하고 직관적인 기능을 제공하는데, 패턴 매칭을 지원하고 자동으로 생성자, toString, equals, hashCode 메서드를 생성해 주기 때문에, Scala 프로그래머들이 즐겨 사용하는 클래스 유형 중 하나입니다. 하지만 case class를 사용할 때, 클래스 앞에 final을 붙여야 하는지 고민하는 경우가 있습니다. 이 글에서는 final 키워드를 왜, 언제 사용해야 하는지, 그리고 실제로 필요한 것이지 여부에 대해 살펴보겠습니다.
case class의 특성
먼저 case class가 무엇인지 간단하게 살펴보겠습니다. case class는 일반적인 class 선언부에 case 지시자를 붙혀 작성하며 보통 값 객체(Value Object)로서의 역할을 담당합니다.
// name과 age를 값으로 갖는 Person이라는 case class
case class Person(name: String, age: Int)
case class는 값 객체(Value Object)로서 필요한 기능들을 자동으로 생성해주기 때문에 쉽고 간편하게 사용할 수 있습니다. 주요 특성은 다음과 같습니다.
1. 불변성: 생성된 이후 상태가 변경되지 않으며, 각 필드는 기본적으로 val로 선언됩니다.
2. 패턴 매칭: case class는 패턴 매칭에서 유용하게 사용할 수 있도록 만들어져 있습니다. 이는 프로그램에서 매우 강력한 기능을 제공하며, 패턴 매칭을 통해 복잡한 조건을 간단하게 처리할 수 있습니다.
3. 자동 메서드 생성: case class는 toString, equals, hashCode와 같은 메서드를 자동으로 생성합니다. 덕분에 값 객체로 쉽게 사용할 수 있습니다.
하지만 case class는 기본적으로 final이 아닙니다. 즉, case class는 다른 클래스에 의해 상속될 수 있습니다. 예를 들어, 다음과 같이 case class를 상속하는 코드가 가능합니다:
case class Person(name: String)
class Employee(name: String, id: Int) extends Person(name)
여기서 Employee는 Person 클래스를 상속합니다. 그러나 실제로 case class가 상속되는 경우는 드뭅니다. 그렇다면, 이런 상황에서 final을 사용해야 할까요?
final을 붙여야 하는 이유
case class에 final 키워드를 붙이면 해당 클래스는 더 이상 상속될 수 없습니다. 이는 몇 가지 이유에서 유용할 수 있습니다.
** 1. 불필요한 확장 방지:** 대부분의 case class는 상속될 필요가 없습니다. 값 객체로 사용되기 때문에 상태 변화가 없으며, 상속이 필요한 경우는 거의 없습니다. 따라서 final을 사용하면 의도하지 않은 상속을 방지할 수 있습니다.
2. 성능 최적화: Scala 컴파일러는 final이 붙은 클래스가 상속되지 않음을 알기 때문에 성능을 최적화할 수 있습니다. 컴파일러는 클래스 상속을 고려하지 않고 더 빠르게 동작할 수 있도록 최적화할 수 있습니다.
3. 안정성 확보: 클래스가 상속되면 부모 클래스의 메서드나 속성이 의도치 않게 재정의(override)될 수 있습니다. 이러한 재정의는 예상치 못한 동작을 일으킬 수 있으며, 특히 case class와 같이 불변성을 중시하는 객체에서는 위험할 수 있습니다. final을 사용하면 이러한 예기치 않은 재정의를 방지할 수 있습니다.
언제 final을 생략해도 될까?
반면에 final을 생략해도 문제가 없는 경우도 있습니다. 예를 들어, 클래스가 상속될 가능성이 열려 있어야 하거나, 특정 목적으로 상속이 필요하다면 final을 붙이지 않는 것이 합리적입니다. 다음은 final을 생략할 수 있는 경우입니다.
1. 테스트 목적으로 상속이 필요한 경우: 테스트 환경에서 case class를 상속하여 특정 기능을 목 객체(Mock Object)로 테스트해야 하는 경우가 있습니다. 이때는 final을 붙이지 않고 상속을 허용해야 할 수 있습니다.
2. 확장 가능성을 염두에 두는 경우: 설계 상 클래스가 확장되어야 하는 경우가 있다면 final을 생략할 수 있습니다. 하지만 case class는 주로 확장 가능성이 필요하지 않은 값 객체로 설계되기 때문에 이런 경우는 드뭅니다.
결론: final을 사용하는 것이 좋을까?
대부분의 경우, case class는 상속되지 않는 값 객체로 사용됩니다. 따라서 final을 사용하는 것이 더 안전한 선택입니다. 상속을 허용하지 않으면 불필요한 확장을 방지할 수 있고, 성능 최적화도 기대할 수 있습니다. 또한, 설계적으로 case class는 상속 없이 사용되도록 의도된 경우가 많기 때문에 final을 붙이는 것이 더 나은 선택일 가능성이 큽니다.
결론적으로, 설계적으로 명확한 이유가 없다면 final을 사용하는 것을 권장합니다.
마무리
Scala에서 case class에 final을 붙여야 할지 여부는 설계에 따라 달라집니다. 하지만 대부분의 경우, case class는 확장되지 않는 값 객체로 사용되므로 final을 사용하는 것이 권장됩니다. 값 객체의 안정성과 성능을 고려한다면, final을 붙이는 습관은 좋은 코딩 습관이 될 것입니다.
