공상하는 개발자

[코틀린] 코틀린 익숙해지기 1탄 (확장함수, 클래스, 인터페이스 등) 본문

개발/코틀린

[코틀린] 코틀린 익숙해지기 1탄 (확장함수, 클래스, 인터페이스 등)

공상과학소설 2020. 2. 28. 19:44
반응형

얼리버디 개발자들 모임을 통해 얼리버디 어플을 새롭게 디벨롭을 하겠다는 다짐을 하고 

어떤 계획을 세워야 할까 고민하다가 코틀린에 대해 잘 이해해서 개발을 시작하기로 결정했다.

그럼 시작해보도록 하자!


코틀린의 철학

1. 실용성

-> 코틀린 설계는 대규모 시스템을 개발해본 다년간의 IT업계 경험을 바탕으로 이뤄졌으며, 수많은 소프트웨어 개발자들의 사용에 잘 들어맞을 수 있게 주의 깊게 언어 특성을 선택했다. 코틀린은 연구를 위한 언어가 아니다. 코틀린은 다른 프로그래밍 언어가 채택한 이미 성공적으로 검증된 해법과 기능에 의존한다. 이로 인해 언어의 복잡도가 줄어들고 이미 알고 있는 기존 개념을 통해 코틀린을 더 쉽게 배울 수 있다.

이로 인해 언어의 복잡도가 줄어들고 이미 알고 있는 기존 개념을 통해 코틀린을 더 쉽게 배울 수 있다.

 

2. 간결성

-> 개발자가 코드를 새로 작성하는 시간보다 기존 코드를 읽는 시간이 더 길다는 사실이 잘 알려져 있다. 수정을 하려고 해도 코드를 읽어보고 수정할 부분을 찾는게 먼저이다. 이 과정에서 코드가 더 간단하고 간결할수록 내용을 파악하기가 쉽다. 코틀린은 그러한 간결성이 잘 스며들어있는 언어이다. 코틀린을 만들면서 프로그래머가 작성하는 코드에서 의미가 없는 부분을 줄이고, 언어가 요구하는 구조를 만족시키기 위해 별 뜻은 없지만 프로그램에 꼭 넣어야 하는 부수적인 요소를 줄이기 위해 많은 노력을 기울였다. 게터, 세터, 생성자 파라미터등은 묵시적으로 구현이 되기 때문에 자바에 비해서 코드가 한결 짧아진다. (코틀린을 사용하면서 몸소 느껴봤다.)

 

3. 안전성

-> 일반적으로 프로그래밍 언어가 안전하다는 말은 프로그램에서 발생할 수 있는 오류 중에서 일부 유형의 오류를 프로그램 설계가 원천적으로 방지해준다는 뜻이다. 물론 이것은 절대적인 것은 아니다.

 예를 들어 코틀린은 널 오류 방지를 잘 지원해준다. ? 하나로 널이 될수 있음과 없음을 구분해서 컴파일 시점에서 검사를 통해 오류를 더 많이 방지해줄수 있다.

 

 


클래스와 프로퍼티

클래스라는 개념의 목적은 데이터를 캡슐화하고 캡슐화한 데이터를 다루는 코드를 한 주체 아래 가두는 것이다.

자바에서는 필드와 접근자를 한데 묶어 프로퍼티라고 부른다. 코틀린 프로퍼티는 자바의 필드와 접근자 메소드를 완전히 대신한다. 클래스에서 프로퍼티를 선언할 때는 앞에서 살펴본 변수를 선언하는 방법과 마찬가지로 val이나 var를 사용한다. 

class Person(
    val name: String,
    var isMarried: Boolean
)

val은 읽기전용 프로퍼티로, 코틀린은 값을 저장하기 위한 (비공개) 필드필드를 읽는 단순한 (공개) 게터를 만들어낸다.

var은 쓸 수 있는 프로퍼티로, 코틀린 값을 저장하기 위한 (비공개) 필드(공개) 게터, 세터를 만들어낸다.

 

val person = Person("chan",true)
    println(person.name)
    println(person.isMarried)

자바에서는 person.getName() 으로 불러야 했던 것을 person.name 으로 프로퍼티 이름을 직접 사용해도 코틀린이 자동으로 게터를 호출해줘서 간결하다. 세터 같은 경우에도 person.isMarried = true 를 선언해주면 된다.

 

커스텀 접근자

class Rectangle(val height: Int, val width: Int) {
    val isSquare: Boolean
        get() {
            return height == width
        }
}

위처럼 프로퍼티의 게터를 선언해줄 수 있다. 


확장 함수와 확장 프로퍼티

확장 함수

확장 함수는 어떤 클래스의 멤버 메소드인 것처럼 호출할 수 있지만 그 클래스의 밖에 선언된 함수다. 확장 함수를 보여주기 위해 어떤 문자열의 마지막 문자를 돌려주는 메소드를 추가해보자.

 

String 클래스는 open 키워드가 붙어있지 않다. 따라서, 상속을 받을 수 없다. 멤버함수를 추가 할 수 없다.

코틀린 내장된 클래스는 사용자가 마음대로 멤버함수를 추가 할 수 없다.

확장함수를 이용하면 상속 없이 클래스 외부에서 멤버함수를 추가 할 수 있다.

fun String.lastChar():Char = this[this.length-1]

 

확장함수를 만들려면 추가하려는 함수 이름 앞에 그 함수가 확장할 클래스의 이름을 덧붙이기만 하면 된다.

👉확장함수 형식 

fun 함수를 주입할 클래스명.함수명

 

클래스 이름(String)을 수신 객체 타입이라 부르며, 확장 함수가 호출되는 대상이 되는 값(this)을 수신 객체라고 부른다.

여기서 함수를 주입할 클래스를 리시버타입이라고 한다. 리시버 타입의 멤버 함수(프로퍼티)에 접근하려면 this 키워드를 이용한다.

print("kcy".lastChar())
>>> y

 

확장 프로퍼티

확장 프로퍼티도 확장함수와 동일하게 사용할 수 있다.

val String.isLarge: Boolean
    get() = this.length >= 5

위와 같이 글자수가 5 이상이면 true를 반환하는 확장 프로퍼티를 생성했다. 확장 프로퍼티에는 field가 존재하지 않는다. 즉 field 식별자는 사용 불가능하다.


인터페이스와 추상클래스

인터페이스추상클래스의 차이점

- 인터페이스는 객체를 정의할 목적으로 사용되는 것이 아니라 어떤 객체이든간에 특정 기능을 가질 수 있도록 명시해놓는다.

- 추상클래스는 특정 객체를 정의할 목적으로 사용한다. (객체를 생성할 때 특정한 기능을 추상형으로 명시 해놓는다.)

 

인터페이스

인터페이스 형식

interface abc {
    var aa :String //추상 프로퍼티
    fun myFun() {}
    fun myFun2()	//추상 함수
}

추상함수나 프로퍼티는 상속받은 클래스에서 구현부를 만들어줘야한다!! 안 그래주면 에러가 뜬다.

 

인터페이스는 서로 다른 인터페이스끼리 상속을 받을 수 있다.

 

추상클래스

•추상 클래스 : 추상 함수를 포함하는 클래스를 의미(하나라도 추상함수를 포함하면 그 클래스는 추상클래스이다.)

•추상 함수 : 미완성 함수(실행영역이 없는 함수) 앞부분에 무조건 abstract 키워드를 넣어줘야한다.

 

abstract class AbstractTest{	//추상 함수를 포함하는 추상 클래스
    fun myFun1(){}
    abstract fun myFun2()	//추상 함수
}

 

❗️일반적으로 객체지향언어는 추상클래스와 추상함수를 모두 제공한다.

     코틀린에서는 추상클래스, 추상함수 뿐만 아니라 추상 프로퍼티도 제공한다!!

 

abstract class AbstractTest{
    abstract val aa :String // 추상 프로퍼티
}

 

추상 클래스는 그 자체로는 객체를 생성할 수 없다.

추상 클래스는 선언부에 open 키워드를 명시하지 않아도 다른 클래스가 상속 할 수 있다.

반응형
Comments