필수적이지 않은 부분을 확장 함수로 추출

메서드를 정의할 때는 메서드를 멤버로 정의할지 확장 함수로 정의할지를 결정해야 한다. 두 방법은 거의 비슷하다. 호출법도 비슷하고 리플렉션으로 레퍼런싱하는 방법도 비슷하다. 두 방식 중에 어떤 방식이 우월하다곤 할 수 없다. 상황에 맞게 사용해야 한다.

fun String.nextLine() = this + "\n"

멤버와 확장의 가장 큰 차이점은 확장은 따로 가져와서 써야 한다는 것이다. 그래서 일반적으로 확장은 다른 패키지에 위치한다. 확장은 내가 직접 멤버를 추가할 수 없는 경우 데이터와 행위를 분리하게 설계된 프로젝트에서 쓰인다. 필드가 있는 프로퍼티는 클래스에 있어야 하지만 메서드는 클래스의 public API만 쓴다면 어디 있어도 상관없다.

임포트해서 쓴다는 특징 때문에 확장은 같은 타입에 같은 이름으로 여러 개 만들 수도 있다. 따라서 여러 라이브러리에서 여러 메서드를 받을 수도 있고 충돌이 발생하지도 않는다는 장점이 생긴다. 하지만 같은 이름으로 다른 동작을 하는 확장이 있다는 것은 위험할 수 있다. 위험 가능성이 있다면 그냥 멤버 함수로 만들어서 쓰는 게 좋다. 그렇게 하면 컴파일러가 항상 같은 확장 대신 멤버 함수를 호출할 것이다.

다른 차이점은 확장은 가상이 아니란 것이다. 즉 파생 클래스에서 오버라이드할 수 없다. 확장 함수는 컴파일 시점에 정적으로 선택된다. 따라서 확장 함수는 가상 멤버 함수와 다르게 동작한다. 상속을 목적으로 설계된 요소는 확장 함수로 만들면 안 된다.

확장 함수는 클래스가 아닌 타입에 정의하는 것이다. 그래서 nullable 또는 구체적인 제네릭 타입에도 확장 함수를 정의할 수 있다. 마지막 중요한 차이점은 확장은 클래스 레퍼런스에서 멤버로 표시되지 않는다. 그래서 확장 함수는 어노테이션 프로세서가 따로 처리하지 않는다. 그래서 확장 함수는 어노테이션 프로세서가 따로 처리하지 않는다.

Last updated