강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

akakakakak님의 프로필 이미지
akakakakak

작성한 질문수

자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide)

10강. 코틀린에서 상속을 다루는 방법

get() = 3

작성

·

18

0

안녕하세요. 상속과 별로 연관된 질문은 아닌 듯 하지만 강의에서 나온 부분에 궁금증이 생겨 질문 남깁니다.

 

val swimAbility: Int get() = 3

이라는 예제 코드를 작성하셨는데요.

 

  1. 코틀린은 어차피 필드를 선언하면 게터, 세터를 만들어주고

  2. 필드 선언 시 디폴트 값도 지정해줄 수 있는데

그렇다면 위와 같은 형태의 커스텀 게터는 굳이 구현할 필요 없는 것 아닌가? 하는 생각이 듭니다.

그냥 초기값 3을 갖는 필드를 선언하기만 하면 게터까지 알아서 만들어질 테니까요.

 

그냥 인터페이스의 게터 상속 의도를 표현하기 위해 별 의미나 실 용례는 없는 코드를 작성하신 거라고 봐도 될지? 아니면 저런 방식의 커스텀 게터에 제가 이해하지 못하는 어떤 의미가 있는 것일지가 궁금합니다.

 

감사합니다.

 

답변 2

0

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요! akakakakak님! 🙂

상속을 제외하고 말씀드리자면

그렇다면 위와 같은 형태의 커스텀 게터는 굳이 구현할 필요 없는 것 아닌가?

에 대해서 저도 동일하게 생각합니다. 즉, 단일 클래스라면 custom getter를 사용하지 않고 그냥 프로퍼티를 쓰면 된다고 생각해요! 심지어 특정 클래스의 명확한 멤버가 아니라면 companion object에 const val 로 넣어도 좋다고 생각합니다.

 

하지만

그냥 인터페이스의 게터 상속 의도를 표현하기 위해 별 의미나 실 용례는 없는 코드를 작성하신 거라고 봐도 될지?

에 대해서는 조금 애매합니다.

왜냐하면, 인터페이스는 '프로퍼티'를 갖지 못하는데, 인터페이스를 구현하는 각 구현체가 구현체 별로 고정된 프로퍼티를 반드시 갖는 것 처럼 구현하고 싶다면.. custom getter가 필요하기 때문이죠! 추상 클래스라면 프로퍼티를 이용할 수 있겠으나, 인터페이스라면 getter 형태로 풀어낼 수 밖에 없습니다. 🥺

 

답변이 도움이 되었으면 좋겠습니다. 감사합니다! 🙇

akakakakak님의 프로필 이미지
akakakakak
질문자

답변 감사합니다.

그런데 말씀하신 "마치 고정된 프라퍼티를 갖는듯한 인터페이스"가 실무에서 자주 사용되는 개념일까요?

커스텀 게터라는 형태는 없지만 자바에서도 오버라이딩을 활용해 똑같이 그런 형태의 사용이 가능은 할 것인데.. 그런 식의 용례는 본 적이 없어서요.

코틀린에서는 언어 특성 상 그런 사용례가 실재하는지? 빈번한지? 궁금합니다.

최태현님의 프로필 이미지
최태현
지식공유자

아하~ 그렇군요 저는 가끔 사용하는 편입니다! BE 개발 관점에서 크게 2가지 패턴이 있는 것 같아요.

첫 번째는 다형성에 대한 객체를 표현할 때 sealed interface를 사용하는 경우입니다. sealed interface를 표현해야 하는데 각 유형별로 다른 고정된 값을 써야 하는 경우 (예를 들어 A 타입은 수수료율이 4%이고 B 타입은 3%라거나..) 인데요, DTO에 쓰일 때도 있고 Domain Layer에 쓰일 때도 있고 필요하면 사용하는 편인 것 같아요.

두 번째는 위의 예시처럼 서비스 계층에서 인터페이스를 사용할 때 입니다. 대표적으로 여러 유형에 대한 Resolver를 생각해보면 몇 가지 바리에이션이 가능하긴 하지만... 이런 식으로도 구현 가능합니다.

enum class XX {
  A, B // XX 를 다루는 Resolver는 A와 B 타입이 있다
}

interface XXResolver {
  val type: XX
}

class AResolver : XXResolver {
  override val type: XX
    get() XX.A
}

이제 여기서 List<XXResolver> 를 갖고 있는 XXResolverFacade or XXResolverComponents 같은 클래스를 만들고

class XXResolverFacade(
  val xResolvers: List<XXResolver>
) {
  fun handle(type: XX) {
    // 필요하면 init 과정에서 map 화 시켜 메모리 캐싱이 가능
    this.xResolvers.filter { it.type == type }!!.handle()
  } 
}

같은 패턴으로 쓸 수 있어요

주입 자체를 Map<Enum, XXResolver> 로 받을 수도 있지만, 그러면 @Component 에 문자열로 직접 이름을 지정해야 하고 Enum과는 호환이 잘 되지 않는 느낌이라.. 요즘에는 이 방식을 조금 더 선호합니다.

꼭 언어 특징이라기 보다는 결국 다형성을 통해 어떤 상황에서 어떻게 추상화 할 때 이 방식을 적용하는가 정도인 듯 해요!

답변이 도움이 되었으면 좋겠습니다. 감사합니다 🙇

0

안녕하세요, 인프런 AI 인턴입니다. akakakakak님.

질문 주신 내용은 코틀린의 커스텀 게터와 관련된 이해를 돕기 위한 것입니다. 커스텀 게터는 단순히 값을 반환하는 것 이상으로, 호출 시마다 계산이나 특정 로직을 수행할 필요가 있을 때 유용하게 사용됩니다. 따라서 단순히 초기값을 설정하는 것이 아니라, 값을 반환하는 로직을 포함할 수 있습니다.

예를 들어, 어떤 프로퍼티가 항상 계산된 값을 반환해야 할 때 커스텀 게터를 사용할 수 있습니다. 위의 예제에서는 val swimAbility: Int get() = 3라고 되어있지만, 실제로는 복잡한 계산이나 조건에 따라 다른 값을 반환하는 것이 가능할 수 있습니다.

기본적으로 필드를 선언하면 게터/세터가 자동 생성되지만, 커스텀 게터를 통해 다양한 상황에 따른 값 반환을 제어할 수 있다는 점에서 유용성이 있습니다. 예제에서는 인터페이스나 기타 상위 클래스에서 요구하는 특정 계산 로직이 있을 경우, 이를 게터 내에서 구현해 사용하게 됩니다.

아래 관련된 질문과 답변을 참고하시면 도움이 될 것 같습니다:
- Custom Getter 에 대해 질문이 있습니다.

이 내용이 귀하의 이해에 도움이 되길 바랍니다. 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

akakakakak님의 프로필 이미지
akakakakak

작성한 질문수

질문하기