[Kotlin] 코틀린 기초(2) - enum

sw·2021년 12월 26일
0

1. enum 클래스

Enum은 열거형이라 불리며, 서로 연관된 상수들의 집합이다.

2. enum을 사용하지 않고 상수를 정의하는 다양한 방법

  1. const val 사용
// fruit
const val APPLE = 1
const val PEACH = 2
const val BANANA = 3
// company
// const val APPLE = 1
const val GOOGLE =2
const val NAVER = 3 

fun main() {
    val type = APPLE
    when (type) {
        APPLE -> println("사과")
        PEACH -> println("복숭아")
        BANANA -> println("바나나")
    }
}

-> 상수가 늘어날수록 가독성이 떨어지고, 각각의 상수 집합에서 같은 이름으로 정의된 상수가 있다면 중복된 이름이기 때문에 컴파일 단계에서 오류가 발생한다.


  1. 인터페이스 사용
    - Kotlin에서는 interface에 상수를 정의할 수 없기 때문에 아래 코드부터는 Java로 작성했다!
// fruit
interface FRUIT{
    int APPLE = 1, PEACH =2, BANANA =3;
}

interface COMPANY{
    int APPLE = 1, GOOGLE = 2, NAVER = 3;
}

public class EnumExample{
	public static void main(String[] args) {
		
		int type = COMPANY.APPLE;
		
		switch(type) {
		case FRUIT.APPLE:
			System.out.println("사과");
			break;
		
		case FRUIT.PEACH:
			System.out.println("복숭아");
			break;
		
		case FRUIT.BANANA:
			System.out.println("바나나");
			break;
		}
				
	}
}

-> FRUIT.APPLECOMPANY.APPLE 모두 값이 정수 1이기 때문에 type이 COMPANY.APPLE임에도 에러를 발생시키지 않고 사과를 출력해주고 있다. 이렇게 코드를 구현하게 되면 런타임 단계에서 예기치 못한 문제를 마주치게 된다.

  1. Fruit과 Company 클래스를 만들고 클래스 변수로 해당 클래스의 인스턴스를 사용
class Fruit{
    public static final Fruit APPLE  = new Fruit();
    public static final Fruit PEACH  = new Fruit();
    public static final Fruit BANANA = new Fruit();
}

class Company{
    public static final Company GOOGLE = new Company();
    public static final Company APPLE = new Company();
    public static final Company ORACLE = new Company();
}
 
public class EnumExample {
     
    public static void main(String[] args) {
        if(Fruit.APPLE == Company.APPLE){
            System.out.println("type이 같다.");
        }	
        // 컴파일 오류 발생
    }
}

-> 서로 다른 타입의 상수에 대해서는 비교를 금지시키지만 switch문에서 사용할 수 없고 선언이 너무 복잡하다는 문제점이 있다.

enum Fruit{
    APPLE, PEACH, BANANA;
}
// 열거형을 사용하게 되면 다음과 같이 간단히 사용할 수 있다. 
// 위의 코드는 아래코드와 사실상 같다.

class Fruit{
    public static final Fruit APPLE  = new Fruit();
    public static final Fruit PEACH  = new Fruit();
    public static final Fruit BANANA = new Fruit();
    private Fruit(){}
}



3. enum 사용

// fruit
enum class Fruit {
    APPLE, PEACH, BANANA
}

// company
enum class Company {
    APPLE, GOOGLE, NAVER
}

fun main() {
    /*
        if(Fruit.APPLE == Company.APPLE){
            println("type이 같다.")
        }   // 컴파일 오류 발생
    */

    val type = Fruit.APPLE
    when (type) {
        Fruit.APPLE ->
            println("사과")
        Fruit.PEACH ->
            println("복숭아")
        Fruit.BANANA ->
            println("바나나")
        
    }
}

enum에서도 일반적인 클래스와 마찬가지로 생성자와 프로퍼티를 선언한다. enum 클래스 안에 메소드를 정의하는 경우 반드시 enum 상수 목록과 메소드 정의 사이에 세미콜론(;)을 넣어야 한다.

enum class Color(val r: Int, val g: Int, val b: Int) {  // 상수의 프로퍼티를 정의한다.
    RED(255, 0, 0),
    GREEN(0, 255, 0),
    BLUE(0, 0, 255); // 메소드 구분을 위해 세미콜론 사용

    fun rgb() = (r * 256 + g) * 256 + b

}

fun main() {

    println(Color.GREEN.rgb())

}

4. enum을 사용하는 이유

  1. 코드의 가독성이 높아진다.
  2. 인스턴스 생성과 상속을 방지해서 타입 안정성이 보장된다.
profile
끄적끄적

0개의 댓글