프로그래밍 언어/Kotlin

코틀린[Kotlin] #02_코틀린 기초(함수,클래스,프로퍼티,enum)

Tigercow.Door 2020. 12. 5. 23:43


안녕하세요. 문범우입니다.

이번 포스팅에서는 코틀린의 기초에 대해서 알아보도록 합니다.

구체적으로는 함수, 변수, 클래스, 프로퍼티, enum에 대해서 학습합니다.

관련된 내용의 코드는 아래 주소에서 확인하실 수 있습니다.

https://github.com/doorBW/kotlin-study



1. 함수


우선 어느 프로그래밍 언어에서나 시작해보는 "Hello, world!"를 출력해보자.


1
2
3
fun main(args: Array<String>){
    println("Hello, world!")
}
cs


코틀린에서는 위와 같이 간단한 코드로 문자열 출력을 할 수 있다. 본격적으로 코틀린에 대해서 알아보기 이전에 위 코드에서 파악할 수 있는 몇가지를 살펴보자.


- 함수를 최상위 수준에 정의가 가능하다. 즉, 꼭 클래스 안에 함수가 존재해야 하는게 아니다.

- 함수를 선언할 때에는 fun 키워드를 이용한다.

- 파라미터 이름 뒤에 그 타입을 서술한다. 변수 선언시에도 동일하다.

- 표준 자바 라이브러리 함수를 간결하게 사용할 수 있는 래퍼(wrapper)가 존재한다.(System.out.println -> println)

- 코드의 끝에 세미콜론을 붙이지 않는다.


위의 코드와 같은 경우에는 문자열 출력만 진행하고 따로 반환 값은 없는 함수를 나타내고 있다.

그럼 함수의 반환 값이 존재할 때, 반환 타입은 어디에 나타내야 할까?

다음의 함수는 두 숫자를 입력 받고, 그 중 큰 숫자를 반환하는 함수다.


1
2
3
4
5
6
7
8
fun max(n1: Int, n2: Int): Int {
    return if (n1 > n2) n1 else n2
}
 
fun main(args: Array<String>) {
    println(max(75))
    // 7
}
cs


위의 max 함수를 확인해보면 main 함수와 달리 파라미터와 중괄호 사이에 반환 값 타입을 확인할 수 있다.

즉, 코틀린에서는 다음과 같은 함수의 틀을 가진다.


fun <함수이름>(파라미터): <반환 값 타입> {

    함수내용

}


헌데, max 함수의 반환 내용을 살펴보면 if 문이 값을 만들어 내고 있다.

코틀린에서는 if가 값을 만들어 내지 못하는 문(statement)이 아니라 식(expression)이다. 자바에서는 if가 문으로 사용되기 때문에 코틀린과의 다른점 중 하나이다.

추후 하나씩 알아보면서 설명하겠지만, 자바에서는 모든 제어구조가 문이지만, 코틀린에서는 루프구조를 제외한 대부분이 식으로 되어있다.


이번에는 max 함수에 대해 한번 더 살펴보자.

max함수의 본문은 if식 하나로 이루어져 있다. 이러한 경우 함수에서 중괄호를 없애고, return을 없애면서 등호(=)하나로만 표현할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
fun max(n1: Int, n2: Int): Int {
    return if (n1 > n2) n1 else n2
}
 
fun maxShort(n1: Int, n2: Int): Int = if (n1 > n2) n1 else n2
 
fun main(args: Array<String>) {
    println(max(75))
    // 7
    println(maxShort(75))
    // 7
}
cs



위와 같이 maxShort함수는 기존 max함수와 달리 중괄호를 제거하고 등호를 이용하여 '식'을 본문으로 만든 함수이다. 이와 같은 함수를, '식이 본문인 함수'라고 하며 기존의 max함수는 '블록이 본문인 함수'라고 한다.


헌데 식이 본문인 함수에서는 반환 타입을 다음과 같이 생략할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun max(n1: Int, n2: Int): Int {
    return if (n1 > n2) n1 else n2
}
 
fun maxShort(n1: Int, n2: Int): Int = if (n1 > n2) n1 else n2
 
fun maxShortMore(n1: Int, n2: Int) =  if (n1 > n2) n1 else n2
 
fun main(args: Array<String>) {
    println(max(75))
    // 7
    println(maxShort(75))
    // 7
    println(maxShortMore(75))
    // 7
}
cs


식이 본문인 함수에서는 굳이 프로그래머가 반환 타입을 지정하지 않아도 코틀린의 '타입 추론'에 의해 컴파일러가 타입을 체크할 수 있게 된다.



2. 변수


1
2
3
4
5
6
    var number1: Int = 1
    var number2 = 2
    var answer1 = "정답1 입니다."
    var answer2: String
    answer2 = "정답2 입니다."
    var answer3 // error
cs


변수 선언과 초기화는 위와 같이 표현된다.

선언과 초기화를 동시에 진행하는 경우, number1과 같이 타입까지 지정해주거나, number2와 answer1과 같이 타입을 생략할 수 있다.

하지만, 선언과 초기화를 다른 시점에 진행하는 경우에는 선언 시점에 꼭 타입을 지정해주어야 한다.


또한 코틀린에서는 '변경 가능한 변수'와 '변경 불가능한 변수' 2가지가 존재한다.


1
2
3
4
    var mutable_number = 3
    val immutable_number = 3
    mutable_number = 5
    immutable_number = 5 // Val cannot be reassigned
cs


코틀린에서 변수를 선언하는 키워드는 'var'와 'val' 두가지가 있다.

이때, 'var'는 변경 가능한 변수로, 자바의 일반적인 변수와 같다.

하지만 'val'는 변경 불가능한 변수로, 자바에서 final 변수와 같다.


물론, val 변수의 경우참조 자체는 변경 불가이더라도 그 참조 값이 가리키는 객체의 내부값은 변경될 수 있다.

또한, var 변수의 경우 값이 변경 될 수는 있지만 타입은 고정되기 때문에, 다른 타입의 값으로 변경하려고 하면 컴파일 오류가 발생한다.



3. 문자열 템플릿


이번에 알아볼 내용은 '문자열 템플릿'이다. 

println 을 통해 문자열 출력시, 변수 값을 추가하는 예제를 통해 간단하게 확인해보자.


1
2
3
4
    val helloStr = "Hello"
    println("$helloStr kotlin!")
    println("${helloStr} kotlin!")
    // Hello kotlin!
cs


위와 같이 코틀린에서는 $ 기호를 이용하여 변수를 문자열 안에 사용할 수 있다.

이때, 중괄호를 이용하여 변수를 감싸는 것이 더 좋다.


추가로 중괄호를 사용할 때에는 변수말고 식 자체도 넣을 수 있다.


1
2
3
4
5
    val calcNum = 3 + 5
    println("calcNum: ${calcNum}")
    // 8
    println("calcNum: ${3 + 5 + 5}")
    // 13
cs


앞에서 if는 코틀린에서 문이 아니라 식이라고 했다. 그럼 문자열 템플릿을 이용해 다음과 같이 바로 값을 확인할 수 있다.


1
2
    println("Max number in 5 or 3, is ${if (5 > 3) 5 else 3}")
    // 5
cs



4. 클래스와 프로퍼티


우선 자바에서의 간단한 클래스를 살펴보자.


1
2
3
4
5
6
7
8
9
10
11
public class Person {
    private final String name;
    
    public Person(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
}
cs


위의 Person클래스는 Java에서 흔하게 볼 수 있는 형태이다. 위와 같은 클래스를 코틀린에서는 다음과 같이 작성한다.


1
class Person(val name: String)
cs


매우 간단하다.

이렇게 짧은 한줄의 코드가 어떤 의미를 가지고 있는지 잠깐 살펴보자.

우선 코틀린에서 기본 가시성은 public이다. 따라서 class 앞에 public을 생략하였다.

또한 자바 코드를 보면 name 프로퍼티는 setter가 없기에 변경 불가능한 프로퍼티임을 암시할 수 있다. 이때 코틀린에서는 프로퍼티를 정의하며 val와 var의 구분으로 읽기 전용 프로퍼티인지, 쓸 수 있는 프로퍼티인지를 나타낼 수 있다.


그럼 위와 같이 정의한 Person 클래스에 새로운 프로퍼티를 하나 추가한 후 사용해보도록 하자.


1
2
3
4
5
6
7
8
9
class Person(val name: String, var isMarried: Boolean)
 
fun main(args: Array<String>) {
    val person = Person("Door"false)
    println(person.name)
    // Door
    println(person.isMarried)
    // false
}
cs


기존의 Person 클래스에 변경 가능한, isMarried 프로퍼티를 추가하였고, 이후 생성하고 해당 객체에 대한 값을 출력해보았다.

4번 라인에서 Person 객체를 생성 할 때, 자바와는 다르게 new 키워드를 사용하지 않은 걸 볼 수 있다.

또한 5번과 7번 라인에서 객체의 프로퍼티 이름에 직접 접근하면 그에 대한 게터를 코틀린이 호출하는 것을 알 수 있다.

또한 아래와 같이 프로퍼티 게터를 직접 선언할 수도 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Rectangle(val height: Int, val width: Int) {
    val isSquare: Boolean
        get() {
            return height == width
        }
}
 
fun main(args: Array<String>) {
    val rectangle1 = Rectangle(5,4)
    println(rectangle1.isSquare)
    // false
    val rectangle2 = Rectangle(5,5)
    println(rectangle2.isSquare)
    // true
}
cs



5. Enum 클래스


마지막으로 enum 클래스에 대해서 알아보자.


1
2
3
enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}
cs


위의 코드는 코틀린에서 enum class인 Color 정의한 코드이다. 자바와는 달리 class 앞에 enum을 사용해야 한다.


자바와 동일하게, 코틀린에서도 enum은 단순히 값만 열거하지는 않는다. enum 클래스 안에 프로퍼티나 메소드를 다음과 같이 정의할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum class Color(
    val r: Int, val g: Int, val b: Int
) {
    RED(25500), ORANGE(2551650),
    YELLOW(2552550), GREEN(02550), BLUE(00255),
    INDIGO(750130), VIOLET(238130238); // need semicolon
 
    fun rgb() = (r * 256 + g) * 256 + b
}
 
fun main(args: Array<String>) {
    println(Color.BLUE.rgb())
    // 255
}
cs


위의 코드와 같이 enum class에서도 일반적인 class와 동일하게 생성자와 프로퍼티를 선언한다. 또한 해당하는 enum 상수를 정의할 때는 그 상수에 대응되는 프로퍼티 값을 넣어주면 된다.

또한, 이전과는 다르게 enum class에서 메소드를 정의하는 경우에는 필수로 enum 상수 목록의 마지막에 세미콜론을 붙여주어야 한다.



- Quiz

앞에서 학습한 내용들을 바탕으로 몇가지 퀴즈를 풀어보자.


Q1. if가 자바와 코틀린에서 다른점은 무엇인가?



Q2. val 변수와 var 변수의 차이는?



Q3. 코틀린에서 세미콜론을 붙여야 하는 경우는 언제인가?




참고 서적 및 링크

* [Kotlin in Action] - 드미트리 제메로프/스베트라나 이사코바 지음, 오현석 옮김, 에이콘 출판사


728x90