본문 바로가기

프로그래밍(TA, AA)/JVM 언어

[SCALA] object, case class, trait

[object: 객체]

object는 하나 이상의 인스턴스를 가질 수 없는 형태의 클래스로, 객체 지향 설계에서는 singleton이라 한다. new 키워드로 인스턴스를 생성하는 대신 이름으로 직접 해당 객체에 접근한다. 객체는 실행 중인 JVM에서 최초로 접근할 때 자동으로 인스턴스화된다. 객체에 처음 접근하기 전까지는 인스턴스화되지 않는다.


스칼라는 객체에 'main' 메소드를 사용하여 애플리케이션의 진입점으로 셸에서 실행될 수 있는 명령줄 애플리케이션을 생성할 수 있다. 명령줄 애플리케이션을 스칼라에서 생성하려면 입력 인수로 문자열 배열을 취하는 main 메소드를 추가하면 된다. 코드를 컴파일한 이후에 객체 이름을 scala 명령어와 함께 실행하면 된다.



[case class: 케이스 클래스]

case class는 자동으로 생성된 메소드 몇가지를 포함하는 인스턴스 생성이 가능한 클래스이다. 케이스 클래스는 자동으로 생성되는 동반 객체를 포함하는데, 이 동반 객체도 자신만의 자동으로 생성된 메소드를 가지고 있다. 클래스와 동반 객체에 있는 이 메소드들은 모두 클래스의 매개변수 목록에 기반을 두며, 이 매개변수들은 모두 필드를 반복적으로 비교하는 equals 구현과 클래스명/클래스의 모든 필드 값을 출력하는 toString 메소드 같은 메소드들을 만드는데 사용된다.


케이스 클래스는 생성된 데이터 기반 메소드가 주어졌을때 주로 데이터를 저장하는데 사용되는 클래스인 데이터전송 객체를 잘 지원한다. 그러나 케이스 클래스는 계층적인 클래스 구조에서는 잘 동작하지 않는데, 상속받은 필드는 그 유틸리티 메소드를 만드는 데 사용되지 않기 때문이다. 생성된 메소드는 서브클래스에 의해 추가된 필드를 고려하지 않기 때문에 일반적인 클래스가 케이스 클래스를 확장하는 것은 그 생성된 메소드로부터 유효하지 않은 결과를 가져올 수 있다. 그러나 명황하게 정해진 필드들을 가진 클래스를 원한다면 자동으로 생성된 이 메소드는 유용하며, 따라서 케이스 클래스를 활용하는 것이 도움이 된다.


기본적으로 케이스 클래스는 매개변수를 값필드로 전환하므로 val 키워드를 매개변수 앞에 붙일 필요는 없다. 만약 변수 필드가 필요하다면 var 키워드를 사용할 수 있다.


데이터 저장소 용도로는 클래스보다 케이스 클래스가 더 적합하며, 대부분의 함수를 작성할때는 클래스보다 객체가 더 적합하다고 볼 수 있다. 함수 작성에 있어서는 객체와 trait를 더 많이 사용하게 되는데, case class가 데이터를 관리하는데 편의를 제공하는 방식과 같은 방법으로 trait는 함수를 재사용하는데 있어 편리하기 때문이다.



[trait]

trait는 다중 상속을 가능하게 하는 클래스 유형 중 하나다. 클래스/케이스 클래스/객체/트레이트는 모두 하나 이상의 클래스를 확장할 수 없지만, 동시에 여러 트레이트를 확장할 수는 있다. 그러나 다른 유형과 달리 트레이트는 인스턴스화될 수 없다.


트레이트는 타입 매개변수를 취할 수 있어 재사용성이 뛰어나다. 만일 클래스와 하나 또는 그 이상의 트레이트를 확장한다면, with 키워드를 이용하여 트레이트를 추가하기 전에 클래스를 먼저 확장해야 한다. 만약 부모 클래스가 지정되었다면, 그 부모 클래스는 어떤 부모 트레이트보다 앞에 위치해야 한다.


JVM 클래스는 하나의 부모 클래스만 확장할 수 있다. 스칼라 언어가 이론적으로 다중 상속을 지원하더라도, 실제로 컴파일러는 클래스와 트레이트의 긴 한 줄짜리 계층구조를 만들기 위해 각 트레이트의 사본을 만들어 낸다. 이와 같이 상속될 클래스와 트레이트의 수평적인 리스트를 받아서 한 클래스가 다른 클래스를 확장하는 수직적 체인으로 재구성하는 절차를 선형화(linearization)이라 한다. 이는 단일 상속만을 지원하는 실행 환경에서 다중 상속을 지원하는 일종의 대처 방안이다. JVM이 단일 상속만 지원한다는 사실이 모든 클래스 계층구조가 비결정적이며 경쟁 관계의 구성원을 가진 두 트레이트로 혼란을 일으킬 가능성을 배제한다는 점을 보장한다.