기본적인 가시성 변경자와 접근의 제어가시성 변경자는 클래스 외부에서의 접근을 제어한다.클래스의 구현에 대한 접근을 제한함.외부 코드가 클래스 내부 구현에 의존하지 않음.public, protected, private 변경자가 존재하며,기본은 public아무런 변경자가 없으면 기본 선언은 공개자바의 기본 가시성 패키지 전용은 코틀린에 존재하지 않음패키지를 네임스페이스 위한 용도로만 사용패키지에 가시성 제어 적용 X코틀린의 internal 가시성 변경자패키지 전용 가시성에 대한 대안코틀린은 internal 가시성 변경자 도입internal모듈 내부에서만 볼 수 있다의 의미이다. 모듈은 한 번에 한꺼번에 컴파일되는 코틀린 파일들을 의미이클립스 인텔리제이 메이븐 등의 프로젝트가 모듈이 될 수 있다.모듈 내부 가..
자바의 내부 클래스자바의 클래스 내부에서 다른 클래스를 정의하면기본적으로 내부 클래스가 된다.내부클래스는 외부 클래스에 대한 인스턴스 참조를 자동으로 가지게 된다.코틀린에서의 내부 클래스외부 클래스와 내부 클래스는 서로 접근 권한이 없다코드의 캡슐화나 정의를 사용하는 곳에 가깝게 두는 것에 유용한 편이다.중첩 클래스의 사용 예제View 인터페이스와 State 인터페이스를 예로View 의 상태를 직렬화하는 경우에 중첩 클래스를 사용하면 편리하다.Button 클래스의 상태를 저장하는 클래스는 Button 클래스의 내부에 선언하면 편리하다.State 인터페이스를 구현한 ButtonState 클래스를 정의하여 Button에 대한 구체적인 정보를 저장한다.class Button : View { override f..
3중 따옴표 문자열이스케이프를 피하고 여러 줄의 문자열을 쉽게 작성가능하게 해준다Java17 에서도 등장했던걸로 기억한다.val kotlinLogo = """ .| // .| // .|/ \""" fun main() { println(kotlinLogo.trimMargin(".")) } | // | // |/ \이게 뭔데..?코틀린 로고라는데..귀찮다 그냥 알아 먹도록trimMargin지정된 마커 . 앞의 공백을 제거해서여러 줄의 문자열을 더 깔끔하게 출력할 수 있다.여러 줄 문자열의 특징문자 이스케이프 불필요\n, \t 같은 이스케이프 문자 사용할 필요가 없어짐줄 바꿈이 포함됨들여쓰기의 제어trimMargin 함수로 들여쓰기 관리가 가능해진다.문자열 템플릿과 결합$ 같은 문자열을 안에 직접 넣을 수 없..
fun saveUser(user: User) { if (user.name.isEmpty()) { throw IllegalArgumentException("Can't save user ${user.id}: empty Name") } if (user.address.isEmpty()) { throw IllegalArgumentException("Can't save user ${user.id}: empty Address") } // Save user to the database } fun main() { val user = User(1, "John", 25, "Main St.") saveUser(user) }에서 이름과 주소의 유효성 검사가 중복된다.해당 부분을 로컬 함수로 개선해보자fun saveUser(us..
인터페이스 정의 및 구현 인터페이스 정의 interface Clickable { fun click() } click은 추상 메서드임. 인터페이스 구현 interface Clickable { fun click() } class Button : Clickable { override fun click() = println("I was clicked") } fun main() { Button().click() } I was clicked extends 와 implements 대신 콜론 (: ) 을 사용하여 클래스의 확장과 인터페이스의 구현을 처리한다. override 키워드는 상위 클래스나 인터페이스의 메서드를 오버라이딩할때 필수적으로 사용됨. 디폴트 구현과 다중 인터페이스 구현 디폴트 구현을 인터페이스에 제공..
확장 프로퍼티 정의읽기 전용 확장 프로퍼티val 키워 사용 게터 구현이 필요함변경 가능한 확장 프로퍼티var 키워드를 사용하여 정의하고, 게터와 세터를 모두 구현해야함사용읽기 전용 확장 프로퍼티fun String.lastChar(): Char = this.get(this.length - 1) fun main() { val lastChar = "Kotlin".lastChar println("lastChar = $lastChar"); } //lastChar = n변경 가능한 확장 프로퍼티var StringBuilder.lastChar: Char get() = get(length - 1) set(value: Char) { this.setCharAt(length - 1, value) } fun main() { ..