목차
개요
Kotlin에는 기본적인 클래스, 추상 클래스, 인터페이스 외에도 Data Class, Enum Class, Sealed Class가 존재한다. 물론 Enum Class는 Java에도 존재하는 개념이지만 Data Class와 Sealed Class는 Java에는 존재하지 않는 Kotlin만의 특별한 클래스이다. 이번 포스트에서는 이러한 Kotlin의 특별한 클래스에 대해 정리한다.
Data Class
Data Class는 주로 DB를 다루는 앱을 개발할 때 각 DTO(Data Transfer Object)나 VO(Value Object)를 작성할 때 사용할 수 있는 특수한 클래스이다. Java에서 DTO나 VO를 작성할 때 getter, setter를 비롯하여 equals()
, hashCode()
, toString()
메소드를 작성해야 하는 경우가 있는데 Kotlin에서는 이들을 모두 포함하는 Data Class를 손쉽게 작성할 수 있다.
Data Class를 선언할 때는 data class
키워드를 사용하여 선언한다. 그 외에는 일반적인 클래스를 작성하는 것과 동일하게 작성하면 된다. Data Class의 특징은 클래스를 선언하기만 해도 getter, setter, equals()
, hashCode()
, toString()
이 모두 정의된다는 점이다. 물론, Java를 사용할 때도 IDE의 도움을 받거나 Lombok을 사용하여 위 내용들을 손쉽게 작성할 수 있지만 Kotlin에서는 IDE의 도움 없이 단순히 Data Class만 선언하더라도 위 내용들이 정의된다는 차이가 있다. 이 점을 제외하면 Data Class도 일반 클래스와 동일하게 메소드를 작성할 수 있다.
// Java
public class MemberDTO {
private String id;
private String password;
public MemberDTO(String id, String password) {
this.id = id;
this.password = password;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MemberDTO memberDTO = (MemberDTO) o;
if (!id.equals(memberDTO.id)) return false;
return password.equals(memberDTO.password);
}
@Override
public int hashCode() {
int result = id.hashCode();
result = 31 * result + password.hashCode();
return result;
}
@Override
public String toString() {
return "MemberDTO{" +
"id='" + id + '\'' +
", password='" + password + '\'' +
'}';
}
}
Java에서는 이렇게 길게 작성해야 하는 내용이
// Kotlin
data class MemberDTO(var id: String, var password: String)
Kotlin에서는 이 한 줄로 모든게 정의된다. 실제로 동작시켜 보면 잘 작동한다는 것을 알 수 있다.
Data Class는 일반적으로는 상속이 불가능하다는 특징이 있다. data class
앞에 open
을 붙이게 되면 두 키워드가 호환되지 않는다는 에러가 나타난다.
Enum Class
Enum Class는 Java와 다르지 않다. Java와 Kotlin의 기본적인 클래스 문법 차이를 제외하면 단지 Java에서는 선언 키워드가 enum
인데 Kotlin에서는 enum class
로 선언한다는 차이가 있을 뿐이다. 클래스 상속이 불가능하지만 인터페이스 구현은 가능하며, 싱글톤으로 작동한다는 점까지 동일하다.
// Java
public enum DetailedMajor {
DB("데이터베이스"),
AI("인공지능"),
NETWORK("네트워크"),
MOBILE("모바일"),
OS("운영체제");
private final String major;
DetailedMajor(String major) {
this.major = major;
}
public String getMajor() {
return major;
}
}
// Kotlin
enum class DetailedMajor(val major: String) {
DB("데이터베이스"),
AI("인공지능"),
NETWORK("네트워크"),
MOBILE("모바일"),
OS("운영체제")
}
Enum Class의 활용 방법은 Java와 Kotlin이 약간 차이가 있다. Kotlin에서 when 문에서 조건을 검사할 값에 Enum 타입을 사용하면 IntelliJ에서 자동으로 when에 누락된 값이 있다는 것을 알려주고 when의 조건에 모든 값을 추가할 수 있게 해준다. 또한 컴파일러가 해당 Enum 타입의 모든 값을 알고 있기 때문에 when 문을 expression으로 사용할 때 Enum 타입의 모든 값을 작성했다면 else를 작성하지 않아도 된다.
Sealed Class
Sealed Class는 기본적으로는 추상 클래스인데 몇 가지 특이한 점이 있다. Sealed Class의 자식 클래스는 반드시 같은 패키지 내에서만 선언할 수 있으며, 추상 클래스이기 때문에 그 자체로는 객체를 생성할 수 없다. Sealed Class는 컴파일 타임에 자식 클래스의 타입을 모두 기억하기 때문에 Enum Class처럼 사용할 수 있다.
package com.kotlin
sealed class Animal(var name: String) {
protected abstract fun eat(food: String)
}
package com.kotlin
class Dog(name: String) : Animal(name) {
override fun eat(food: String) = println("강아지가 ${food}를 맛있게 먹습니다.")
}
class Cat(name: String) : Animal(name) {
override fun eat(food: String) = println("야옹이가 ${food}를 냠냠 먹어요.")
}
Sealed Class를 when 문과 함께 사용하면 Enum Class와 마찬가지로 when 문의 조건에 누락된 자식 클래스가 존재한다는 것을 알려주고 한 번에 추가할 수 있게 해준다. when문을 expression으로 사용할 때 모든 자식 클래스 타입을 작성했다면 else가 필요없다는 점도 동일하다.
마무리
이번 포스트에서는 Kotlin의 특수한 클래스인 Data Class, Enum Class, Sealed Class에 대해 정리하였다. 이러한 특수 클래스를 잘 사용하면 코드의 가독성을 늘리면서 코드의 길이는 줄여 코드가 깔끔해지는 효과를 얻을 수 있다. 이러한 편의성에 힘입어 Java에서도 JDK16부터 Data Class에 대응되는 Record Class가, JDK17부터 Sealed Class가 추가되었다고 한다.
다음 포스트에서는 Kotlin의 커스텀 getter와 setter에 대해 정리할 예정이다.
댓글 피드백은 언제나 환영합니다.
'Programming Language > Kotlin & Java' 카테고리의 다른 글
Kotlin 기본 문법 11 : 스코프 함수(let, run, also, apply, with) (0) | 2022.12.26 |
---|---|
Kotlin 기본 문법 10 : 커스텀 getter와 setter (1) | 2022.12.22 |
Kotlin 기본 문법 8 : 정적 변수와 정적 메소드(feat. companion object) (0) | 2022.12.14 |
Kotlin 기본 문법 7 : 추상 클래스/인터페이스와 클래스의 상속 (0) | 2022.12.13 |
Kotlin에서 두 객체의 비교(CompareTo) (0) | 2022.12.09 |
댓글