구현을 위해 검색한 코드를 그런가부다~ 하고 따라 쓴 것이 많다. 어렵지도 않은 내용이지만 막상 혼자 작성하면 활용하지 못하는 내용이 많다. 되짚어보는 겸 정리해두고 자연스럽게 사용해보자.
abstract
BaseActivity나 BaseFragment에서 사용하던 abstract class 혹은 abstract fun은 각각 추상클래스와 추상메소드를 말한다.
추상클래스는 객체 생성이 불가한 클래스로 반드시 상속받은 자식클래스에서 해당 메소드를 오버라이딩하여 구현해야한다.
추상메소드는 추상클래스에서만 선언이 가능하며, 추상클래스를 상속받은 자식클래스가 반드시 구현해야하는 메소드다.
BaseActivity나 BaseFragment에 해당 키워드를 사용한 이유는 Base 자체는 객체로 생성되어서는 안되며, 뷰단에서 공통적으로 반드시 구현해주어야 하는 부분을 강제하기 위함이었을 것이다.
open
자바에서는 final 키워드가 붙지 않으면 기본적으로 다른 클래스에서 상속이 가능하지만, 반대로 코틀린은 기본이 final. 상속 가능한 클래스를 만들기 위해서 혹은 오버라이드 가능한 메소드를 만들기 위해서는 open 키워드를 붙여주어야 한다.
BaseActivity에서 컨테이너 아이디를 리턴해주는 메소드에 해당 키워드가 붙었던 것은 상속받은 액티비티에서 리턴 값을 새로 정의해주어야 하기 때문이다.
protected
먼저 코틀린의 접근제한자는 public, protected, internal, private이 있다.
지금까지 접근제한자로 private를 많이 썼는데 private은 선언된 클래스 내에서만 접근 가능하다. 상속받은 클래스에서도 접근하지 못하는 것. BaseActivity에서 선언되는 메소드의 경우 외부 접근은 피해야 하지만 하위클래스인 자식클래스에서의 접근은 허용해야 하는 경우가 있을 수 있다. 이 때, protected를 사용하므로써 하위 클래스에서 해당 메소드에 접근할 수 있다 (ex. binding...)
get()
프로퍼티 = 필드 + getter/setter(접근자 메소드)
직접 내부 데이터인 필드에 접근하지 못하고 접근자 메소드를 통해 접근하여 데이터를 캡슐화한다. 근데 매번 Int value, fun getName(), fun setName() 이렇게 작성하면 코드 양이 어마어마해진다. 이에 코틀린은 getter와 setter를 컴파일 단계에서 자동으로 생성해주므로써 코드를 더욱 간결하게 만들었다. (* 키워드에 따라 생성되는 메소드 다름)
그리고 이 접근자 메소드를 커스텀할 수 있다. 필드를 생성하는 동시, 고정 값을 할당할 때 get() = ... 와 같이 쓸 수 있다. get(){}, set(){}도 마찬가디로 접근자 메소드를 커스텀하여 호출할때 특정 연산을 할 수 있다.
@LayoutRes
layout 리소스를 참조하겠다는 어노테이션
예를 들어, abstract class BaseFragment<B: ViewDataBinding>(@LayoutRes val layoutId: Int): Fragment() { ... } 에서 파라미터로 받는 Int 값이 layout 리소스 아이디임을 명시 + 컴파일시 잘못된 리소스(drawable, sting...)를 전달하는 것을 방지할 수 있다.
.invoke()
invoke 예약어는 이름없이 호출될 수 있는 함수를 의미한다.
사실 지금까지 .inflate(inflater, container, false) 이렇게 작성하던 것은 일반 메소드 호출처럼 보이지만 invoke 메소드를 통해 호출되던 것이다. 원래대로 호출하게 되면 inflate.invoke(inflater, container, false) 이런 식이 된다.
도움받은 곳
추상클래스(abstract class), 추상메소드(abstract method) 사용 방법
[Kotlin] 키워드 정리 (open, internal, data class)
[Kotlin] 접근 제한자(Visibility Modifier)
[kotlin] 접근자 메서드
Android Annotation 정리
[Kotlin] invoke 함수는 무엇일까 ?
+ GPT