#kotlin

코틀린 기초2

1jeongg 1jeongg Follow 2024년 03월 10일 · 3 mins read
Share this

04. 클래스, 객체, 인터페이스

클래스

코틀린은 자봐와 달리 콜론(:)을 붙이고 인터페이스와 클래스 이름을 적는 것으로 클래스 확장과 인터페이스 구현을 모두 처리한다.

오버라이딩할땐 반드시 override 변경자를 사용해야 한다.

상속한 인터페이스의 메서드 구현 호출하기 ```kotlin class Button : Clickable, Focusable { override fun click() = println(“I was clicked”)

    // 이름과 시그니처가 같은 멤버 메서드에 대해 둘 이상의 디폴트 구현이 있는 경우
    // 인터페이스를 구현하는 하위 클래스에서 명시적으로 새로운 구현을 제공해야 한다.
    override fun showOff() {
        super<Clickable>.showOff()
        super<Focusable>.showOff()
    }
}
```

클래스와 메서드는 기본적으로 final이다. 취약한 기반 클래스 문제(하위 클래스가 base 클래스에 대해 가졌던 가정이 base 클래스를 변경함으로써 깨져버림)로 인해 상속을 최소화하고 싶은 것이다.

클래스 내에서 상속 제어 변경자 의미

변경자 이 변경자가 붙은 멤버는… 설명
final 오버라이드 할 수 없음 클래스 멤버의 기본 변경자다.
open 오버라이드 할 수 있음 반드시 open을 명시해야 오버라이드 할 수 있다.
abstract 반드시 오버라이드해야 함 추상 클래스의 멤버에만 이 변경자를 붙일 수 있다. 추상 멤버에는 구현이 있으면 안된다.
override 상위 클래스나 상위 인스턴스의 멤버를 오버라이드하는 중 오버라이드 하는 멤버는 기본적으로 열려있다. 하위 클래스의 오버라이드를 금지하려면 final을 명시해야 한다.

코틀린에선 internal 가시성 변경자를 사용하면 같은 모듈 안에서만 볼 수 있다.

코틀린에선 최상위 선언에 대해 private 가시성을 허용한다.

protected 멤버는 오직 어떤 클래스나 그 클래스를 상속한 클래스 안에서만 보인다.

자바와 코틀린의 중첩 클래스와 내부 클래스 관계 | 클래스 B 안에 정ㅇ의된 클래스 A | 자바에서 | 코틀린에서 | | 중첩 클래스(바깥쪽 클래스에 대한 참조를 저장하지 않음) |static class A |class A| | 내부 클래스(바깥쪽 클래스에 대한 참조를 저장함)| class A |inner class A|

sealed 변경자를 사용하면 그 상위 클래스를 상속한 하위 클래스 정의를 제한할 수 있다. 따라서 when을 사용할 때 따로 else 분기를 만들지 않아도 괜찮다.

객체의 동등성: 코틀린에서 == 연산자는 객체의 동등성을 검사한다. 따라서 비교할 때는 equals를 override해줘야 한다. 그런데 이때 객체가 제대로 작동하지 않는 경우가 있다. 그 이유는 hashCode를 정의하지 않았기 때문이다. 하 근데 이런거 다 재정의해주려면 힘들다. 그래서 코틀린은 data class를 만들어서 toString, equals, hashCode 와 같은 메서드를 정의해주고 정확성과 일관성을 한 번더 검사해준다.

05. 람다

람다는 기본적으로 다른 함수에 넘길 수 있는 작은 코드 조각을 뜻한다.

  • 사용
    • 이벤트 발생시 핸들러 실행
    • 데이터 구조의 모든 원소에 이 연산을 적용
  • 위험성
    • 람다를 이벤트 핸들러나 다른 비동기적으로 실행되는 코드로 활용하는 경우 함수 호출이 끝난 다음에 로컬 변수가 변경 될 수 있다.
        fun click(button: Button): Int {
        var clicks = 0
        button.onClick { clicks++ }
        return clicks // 항상 0을 반환함 (핸들러가 clicks를 반환한 뒤 호출되기 때문)
        }
      
  • 멤버참조 (::)
    people.maxBy(Person::age) == people.maxBy{ it.age } == people.maxBy{ p -> p.age }

count vs size

people.filter(canBeInClub).size 이런 코드를 살펴 보자.

해당 코드에선 조건을 만족하는 모든 원소가 들어가는 중간 컬렉션이 생겨 오히려 불필요하다. count를 사용하게 되면 조건을 만족하는 원소의 개수만을 추적하지 원소를 따로 저장하진 않기에 더 효율적이다.

count가 더 효율적!

지연 계산 컬렉션 계산

시퀀스를 사용하면 중간 임시 컬렉션을 사용하지 않고도 컬렉션 연산을 연쇄할 수 있다. asSequence 확장 함수를 호출하면 어떤 컬렉션이든 시퀀스로 바꿀 수 있다. 시퀀스를 사용하면 더 효율적이기 때문에 큰 컬렉션에 대해 연산을 연쇄할 땐 이걸 쓰자!!!



1jeongg
Written by 1jeongg Follow

I'm studying Android development by Kotlin and Spring by Java