강의

멘토링

커뮤니티

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

양성빈(Robert)님의 프로필 이미지
양성빈(Robert)

작성한 질문수

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

9강. 코틀린에서 클래스를 다루는 방법

강의 복습하면서 생긴 질문

작성

·

18

·

수정됨

1

태현님 안녕하세요! 해당 강의를 듣던 중 의문점이 있어서 질문을 드릴려고 합니다.

public class Person {
  private final String name;
  
  private int age;

  public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }

// getter, setter 생략...
}

위와 같은 예제 코드가 있다고 하면 위와 같은 코드를 코틀린으로 변경하면 강의에서는 아래와 같다고 하셨습니다.

 

class Person(
  val name: String,
  val age: Int,
)

이러면 자동으로 getter/setter를 자동으로 만들어주신다고 하셨는데요. 저는 이것이 자동으로 만들어주는게 아니라 당연하다고 생각합니다. 왜냐하면 프로퍼티 접근 제어자가 public이니까요!

자바도 public으로 변경하면 코틀린처럼 필드에 접근해서 사용이 가능하다고 생각이 드는데요. 이런 케이스에 대해서 태현님의 의견을 좀 더 듣고 싶습니다. 또한, 당연히 코틀린에서는 getter를 호출하겠지만 필드 자체를 private으로 두지 않으면 객체지향 원칙중에 하나로 캡슐화가 좋지 못하다는 판단이 들더라구요! 또한 코틀린에서는 접근제어자를 private으로 두면 당현한 이야기지만 강의에서 설명주신 것처럼 접근이 안되서 강제 getter/setter를 만들어야 하는데 이것에 대해도 듣고 싶습니다.

 

다음 질문으로는 생성자 관련 질문입니다.

자바는 아래처럼 생성자를 여러개 만들 수 있습니다.

public class Person {
  private String name;
  
  private int age;

  public Person(String name) {
  this.name = name;
 }

 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }

// getter, setter 생략...
}

논리적으로 도메인 흐름상 하나의 파라미터만 있는 생성자는 사용되지를 않겠지만 이런 케이스에서 코틀린은 어떻게 처리가 가능할까요? 코틀린에서는 설명해주시기로 부생성자로 만들지만 부생성자는 주생성자를 호출해야 하는 꼴로 가야한다고 답변을 주셔서요! 이에 대해 궁금합니다!

답변 1

1

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

안녕하세요!! 언제나 그렇듯 질문 주셔서 감사합니다.

하나씩 답변 드려 보겠습니다!

이러면 자동으로 getter/setter를 자동으로 만들어주신다고 하셨는데요. 저는 이것이 자동으로 만들어주는게 아니라 당연하다고 생각합니다. 왜냐하면 프로퍼티 접근 제어자가 public이니까요!

자바도 public으로 변경하면 코틀린처럼 필드에 접근해서 사용이 가능하다고 생각이 드는데요. 이런 케이스에 대해서 태현님의 의견을 좀 더 듣고 싶습니다

는 아마 이런 의견이신 것 같아요!

public class Person {
  public String name;
  public int age;
}

처럼 Java 에서도 퍼블릭 클래스 + 퍼블릭 필드를 갖고 있다면 아래 코드와 다를게 없는데

왜 굳이 강의에서

class Person(
  val name: String,
  val age: Int,
)

라는 코드를 "자동으로 getter/setter를 자동으로 만들어준다" 라고 표현했는가? 어차피 그게 그거 아닌가?

 

이에 대한 제 생각은 겉으로 보기에는 그럴 수 있어도 실제 코틀린이 .class 로 변환되는 상황에서 동작하는 구문을 정확히 알려드는게 좋다고 생각했어요. 이런 내용을 잘 알고 있어야 custom getter 와 같은 개념도 더 쉽게 이해할 수 있다고 생각하거든요~ 충분히 표면적으로 다를게 없는 것처럼 느끼실 수 있다고 생각합니다.

 

또한, 당연히 코틀린에서는 getter를 호출하겠지만 필드 자체를 private으로 두지 않으면 객체지향 원칙중에 하나로 캡슐화가 좋지 못하다는 판단이 들더라구요! 또한 코틀린에서는 접근제어자를 private으로 두면 당현한 이야기지만 강의에서 설명주신 것처럼 접근이 안되서 강제 getter/setter를 만들어야 하는데 이것에 대해도 듣고 싶습니다.

다음으로 이 내용에 대해서도 말씀을 드려보면, "캡슐화" 에 대한 사람들의 생각이 모두 다를 수 있다고 생각해요. 저는 필드 자체가 private 이라면 당연히 좋지만 만약 getter가 반드시 필요한 상황이라면, 이것이 캡슐화를 크게 해치는가? 라고 생각했을 때 그렇지 않다고 봅니다. 물론 완전무결한 private 필드만을 갖고 있는 클래스 보다야 캡슐화가 깨져 있다고 볼 수 있지만, 매우 당연하게도 실무에서 private 필드만 사용해서 기능을 구현하는 것은 불가능합니다. 그렇다면 결국 어느 지점에서는 public한 접근이 어느정도 필요한데요 저는 그 타협점이

  • getter는 public을 자유롭게 써도 되지만, 꼭 필드를 가져가야만 하는지 (흔히 얘기하는 디미터 법칙을 생각할 수 있죠) 한 번 쯤 더 고민해야 한다고 보고

  • setter는 코드 편의성을 위해 public으로 열어두더라도 절대 객체 바깥에서 사용해서는 안된다

라고 생각합니다. 사람마다 의견이 다를 수 있다고 생각하지만, 저는 개인적으로 위 타협안을 적용했을 때 가장 좋은 결과물을 만들 수 있었다고 생각해요!

 

논리적으로 도메인 흐름상 하나의 파라미터만 있는 생성자는 사용되지를 않겠지만 이런 케이스에서 코틀린은 어떻게 처리가 가능할까요? 코틀린에서는 설명해주시기로 부생성자로 만들지만 부생성자는 주생성자를 호출해야 하는 꼴로 가야한다고 답변을 주셔서요!

마지막으로 이 질문에 대해서도 답변 드리면~ 코틀린에서는 default parameter를 사용할 수 있습니다.

class Person(
  val name: String,
  val age: Int = 0,
)

과 같은 클래스를 작성하시면 밖에서는 Person("A") 로 이름만 초기화 할 수도 있고, Person("A", 10) 처럼 nameage 모두를 초기화 할 수도 있습니다.

매개변수가 완전히 다른 경우는 secondary consturctor를 사용해야 겠지만, 그렇지 않다면 보통 이 선에서 해결되더라고요~

 

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

태현님 언제나 항상 좋은 답변 감사드립니다.

양성빈(Robert)님의 프로필 이미지
양성빈(Robert)

작성한 질문수

질문하기