[TIL] 20230719: Kotlin In Action 4장 (3)

ERyukSa·2023년 7월 21일
0

TIL

목록 보기
6/6

학습 내용

1. by 키워드로 클래스의 인터페이스 구현을 다른 '객체'에 위임할 수 있다.

특정 인터페이스에 기능을 확장하고 싶을 때 기존에 잘 구현된 구현 클래스를 바탕으로 편하게 확장하고 싶을 때 사용할 수 있다.

대표적으로 데코레이터 패턴에 by 키워드를 이용할 수 있다. 확장할 기능 외의 함수 구현은 다른 객체에게 맡기고, 원하는 메서드만 오버라이딩한다.

그러면 다른 추상 메서드를 오버라이딩 할 필요가 없기 때문에
IDE 도움 없이도 편하게 추상 메서드를 구현할 수 있으며 코드베이스를 깔끔하게 유지할 수도 있다.

예시

class MyList<T>(
	private val innerList: MutableList<T> = arrayListOf()
) : MutableList<T> by innerList {
	/* 
    MutableList의 수많은 추상 메서드를 일일이 나열하지 않아도 된다. 
    그럼에도 MyList의 인스턴스로 MutableList의 모든 인터페이스를 사용할 수 있다.
    그 구현을 innerList에게 위임한 것이다.
    */
}

2. object 키워드의 공통점

object의 사용처는 여러개지만 클래스를 정의함과 동시에 인스턴스를 생성한다는 공통점이 있다.

2-1. object: 클래스 정의 + 객체 생성 + 변수에 저장 (object declaration)

싱글턴 클래스를 정의할 때 사용한다. 클래스 정의 방식과 같으며 클래스나 인터페이스를 확장할 수 있다.

자바에서 코틀린 object 객체를 사용하고 싶으면, [object 이름].INSTANCE.[멤버] 형식으로 한다.

object MyObject : Parent() {
}

2-2. companion object

object 앞에 companion을 붙이면 특별한 객체가 생성된다. 클래스의 이름은 따로 붙이지 않아도 된다.

그러면 companion object를 감싼 클래스의 이름으로 객체를 참조할 수 있으며, 말 그대로 바깥 클래스의 동반 객체가 된다.

이곳에서는 private constructor에 접근할 수 있다. 또한, 자바의 static 역할을 그대로 구현할 수 있다. 따라서, 팩토리 메서드를 구현하기에 적합하며 그런 목적으로 많이 사용된다.

3. 팩토리 메서드 장점 및 특징

생성자에 이름을 붙일 수 있다.

이미 존재하는 정보(동등한 data class 객체)에 대한 인스턴스를 생성하려고 할 때, 새로 생성하지 않고 캐시에서 이미 존재하는 객체를 반환할 수 있다. 즉, 동등성이 있는 객체를 중복 생성하지 않게 할 수 있다.

팩토리 메서드는 final 클래스에 사용하기 적합하다. 하위 클래스에서 생성자를 오버라이딩 해야 할 수도 있으니까.

4. companion object는 클래스의 정적 인스턴스 변수로 컴파일 되며, 이름이 없으면 자바에서는 Companion으로 접근할 수 있다.

ex) Person.Companion.멤버

2-3. 무명 객체

object로 무명 객체를 정의 및 생성할 수 있다. 자바의 무명 내부 클래스에 해당한다.

그렇게 무명 객체를 생성하는 식을 object expression이라고 한다.

자바와 달리 여러 인터페이스를 구현할 수 있고, 추상 클래스와 인터페이스를 동시에 상속할 수 있다. final이 아닌 변수 필드를 가질 수도 있다.

질문

1. (p.187 마지막) companion object가 클래스의 모든 private 멤버에 접근할 수 있다고?

해결) 말도 안되지 실제로 아니기도 하고. 접근할 수 있는 private member는 construrctor가 유일하다.

2. sealed class와 protected의 관계

해결) sealed class의 상속은 open이며 가시성은 자바의 protected와 같다. 즉, 같은 패키지 안에서만 사용 가능하다.

3. 가시성 변경자에서 가시성이 뭘 뜻하는 거지? 볼 수 있다? or 사용할 수 있다?

해결) 접근 권한. 즉, 사용 권한을 의미한다.

4. sealed class를 이용한 when문 구현은 객체지향에서 지양하는 방식 아닌가?

해결) 잘 설계해도 인스턴스 생성처럼 어딘가에서 한 번은 하위 타입에 따라 분기해야 한다. 그리고 항상 조건문을 없앨 수 있는 게 아니다.

느낀점

  1. by 키워드로 인터페이스 구현을 위임할 수 있는줄 처음 알았다.
  2. 디자인 패턴과 함께 공부하는 있는 것이 내용을 이해하는데 도움이 됐다.

0개의 댓글