[Kotlin] 클래스와 확장함수

강승구·2022년 5월 3일
0

클래스 기본 구조

코틀린 클래스는 class 키워드 다음에 클래스 이름이 오고 그 다음에 클래스 본문이 오는 형태로 정의된다. 클래스 본문은 멤버 정의가 들어있는 블록이다.

class Person {
	var firstName: String = ""
    var familyName: String = ""
    var age: Int = 0
    
    fun fullName() = "$firstName $familyName"
    
    fun show(){
    	println("${fullName()}: $age")
    }
}

클래스 내부에 있는 변수와 함수는 각각 멤버 변수, 멤버 함수 혹은 프로퍼티라고 부른다.
위에서 정의된 Person클래스의 멤버 변수는 firstName, familyName, age이고 멤버 함수는 fullName(), show() 이다.


인스턴스

fun main(){
	//인스턴스 생성
    val person = Person()
    
    //인스턴스의 멤버변수에 접근
    println(person.firstName)
    println(person.familyName)
    println(person.age)
    
    //인스턴스의 멤버함수에 접근
    println(person.fullName())
    person.show()
}

생성자

생성자는 클래스 인스턴스를 초기화해주고 인스턴스 생성 시 호출되는 함수이다.
자바에 비해 코틀린에서는 간단하고 다양하게 생성자를 정의할 수 있다.

주생성자

클래스 헤더의 파라미터 목록을 주생성자라고 부른다.

class Person(firstName: String, familyName: String){
	val fullName = "$firstName $familyName"
}

주생성자 파라미터는 프로퍼티 초기화나 init 밖에서 사용할 수 없다. 그렇기 때문에 생성자 파라미터의 값을 저장할 멤버 프로퍼티를 정의해야한다.

class Person(firstName: String, familyName: String){
    fun show(){
        //error
        println(firstName)
    }
}
class Person(firstName: String, familyName: String){
    val firstName = firstName

    fun show(){
        println(firstName)
    }
}

하지만 코틀린에서는 주생성자 파라미터 앞에 val, var 키워드를 사용하면 자동으로 해당 생성자 파라미터로 초기화되는 프로퍼티를 정의한다. 이때 파라미터를 프로퍼티 초기화나 init 안에서 참조하면 생성자 파라미터를 가리키고 다른 위치에서 참조하면 프로퍼티를 가리키게 된다.

class Person(val firstName: String, familyName: String){
    fun show(){
        println(firstName)
    }
}

init

init은 프로퍼티를 초기화 할 때 추가로 필요한 작업이 있는 경우에 사용한다. init에는 return문이 들어가지 못한다.

class Person{
	var firstName: String
    var familyName: String
	init {
    	this.firstName = firstName
    }
	val fullName = "$firstName $familyName"
}

하나의 식으로 표현하기 어려운 복잡한 초기화 로직을 실행해야 프로퍼티를 초기화 할 수 있는 경우가 있을 수도 있기 때문에 코틀린에서는 init 안에서 프로퍼티를 초기화하는 것을 허용한다.

class Person(fullName: String){
    val firstName: String
    val familyName: String
    
    init {
        val names = fullName.split(" ")
        if(names.size!=2){
            throw IllegalArgumentException("Invalid name : $fullName")
        }
        firstName = names[0]
        familyName = names[1]
    }
}

부생성자


인스턴스 생성

위는 name과 age 프로퍼티

확장 함수

코틀린은 클래스에 상속하거나 디자인 패턴을 사용하지 않고 새로운 기능으로 클래스를 확장 할 수 있는 기능을 제공하는데 이것이 확장(extension)이라는 선언을 통해 이루어진다.

확장 함수를 사용하는 이유

개발자가 직접 만든 클래스의 경우 새로운 함수가 필요할 때 언제든지 쉽게 추가할 수 있다. 하지만 외부 라이브러리를 사용할 때는 함수를 추가하기가 매우 어렵거나 변경할 수 없는 경우가 있다.
외부 라이브러리를 사용하는 경우 코틀린에서 제공하는 확장 함수 기능을 통해 클래스를 확장하여 원하는 대로 새로운 함수들을 만들 수 있다.

즉 기존에 있던 클래스는 뼈대이고 주변에 새로운 함수나 프로퍼티를 붙여서 클래스의 기능을 확장하는 개념이다.


확장 함수의 특징

  • 확장 함수는 상속이나 복잡한 디자인 패턴 없이 간단하게 확장 기능을 만들 수 있다.
  • 보일러 플레이트 코드를 줄일 수가 있다.
  • 정적 바인딩 된다.

사용법

확장함수의 기본 구조는, 원하는 함수명 앞에 확장할 클래스명을 붙여주면 된다.

단, 확장함수는 수신객체의 private이나 protected 멤버를 사용할수 없기 때문에 해당 수신객체의 public 멤버에만 접근이 가능하다.

class Calculator{
    fun plus(a:Int, b:Int) = a+b
    fun minus(a:Int, b:Int) = a-b
}

fun Calculator.multiply(a:Int, b: Int): Int = a*b

또한 확장함수는 static 함수이면서, 클래스 밖에 선언되기 때문에 오버라이딩을 할 수 없다.

profile
강승구

0개의 댓글