보조 프로퍼티 사용
임시적인 보조 프로퍼티 사용하기
보조 필드인 field를 사용하지 않고 추가로 내부의 프로퍼티를 임시로 선언했다.
프로퍼티 오버라이딩
프로퍼티의 오버라이딩 사용하기
게터 세터 예시
lateinit을 사용한 지연 초기화
lateinit을 사용해 지연 초기화하기
객체를 생성할때도 생성자를 않넣고 선언만 할 수 있다.
data class Person(var name: String, var age: Int)
lateinit var person1: Person // 객체 생성의 지연 초기화
fun main() {
person1 = Person("Kildong", 30) // 생성자 호출 시점에서 초기화됨
print(person1.name + " is " + person1.age.toString())
}
lazy를 사용한 지연 초기화
by lazy로 선언된 프로퍼티 지연 초기화하기
by lazy로 객체 지연 초기화
by를 이용한 위임
< val|var|class > 프로퍼티 혹은 클래스 이름: 자료형 by 위임자
클래스 위임 사용하기
observable() 함수와 vetoable()함수의 위임
observable() 함수 간단히 사용해보기
vetoable() 함수를 사용한 최대값 구하기
vetoable()함수는 컬렉션과 같이 큰 데이터를 다룰때 유용하다.
컴페니언 객체 사용하기
컴패니언 객체 사용해보기
컴패니언 객체는 실제 객체의 싱글톤으로 정의된다.
싱글톤이란?
자바에서 컴패니언 객체를 가진 코틀린의 클래스에 접근하도록 하기
@JvmStatic
으로 어노테이션 표기 사용해주기.KCustomer.Companion.login();
과 같이 Companion을 포함하여 java에서 작성한다.프로퍼티를 자바에서 사용하고자 할 경우
@JvmField
어노테이션으 사용하면 된다.object와 싱글톤
내용이 조금 변경된 클래스를 만들때. 새로 하위 클래스를 선언하지 않고 조금 변경한 객체를 생성하고 싶을때.
자바의 경우 익명 내부 클래스를 사용해 새로운 클래스 선언을 피할 수 있지만 코틀린은 object 표현식이나 object 선언으로 조 더 쉽게 처리할 수 있다.
object 선언과 컴패니언 객체 비교하기
- object로 선언된 OCustomer는 멤버 프로퍼티와 메서드를 객체 생성 없이 이름의 점 표기법으로 바로 사용할 수 있다.(싱글톤)
- object 선언 방식을 사용하면 접근 시점에 객체가 생성된다. 그렇기 때문에 생성자 호출을 하지 않으므로 object 선언에는 주 생성자와 부 생성자를 사용할 수 없다. 하지만 초기화 블록인 init이 들어갈 수 있는데 최초 접근에서 실행된다.
- object 선언에서도 클래스나 인터페이스를 상속할 수 있다.
- 만일 자바에서 object 선언으로 생성된 인스턴스에 접근하려면
INSTANCE
를 사용한다.
object 표현식
object 표현식 사용해보기
1번을 통해 익명 객체가 object 표현식으로 만들어졌다. 이 익명 객체는 Superman 클래스를 상속해 fly() 메서드를 오버라이딩 하고 있다.
즉, 하위 클래스를 만들지 않고도 Superman 클래스의 fly() 메서드를 오버라이딩 해 변경했다.
추상 클래스
abstract
라는 키워드와 함께 선언인터페이스
추상 클래스의 정의와 구현
추상 클래스 Vehicle 사용해 보기
추상 클래스에서는 상속을 위해 open 키워드를 사용할 필요가 없다. 마찬가지로 추상 프로퍼티나 메서드에도 open이 필요없다. 하지만 일반 프로퍼티나 메서드를 오버라이딩하려면 open 키워드가 필요하다.
만약 추상 클래스로부터 하위 클래스를 생성하지 않고 단일 인스턴스로 객체를 생성하려면 object를 사용하여 지정할 수 있다.
추상 크래스의 객체 인스턴스
인터페이스
인터페이스의 선언과 구현
interface 인터페이스 이름 [: 인터페이스 이름...] {
추상 프로퍼티 선언
추상 메서드 선언
[일반 메서드 선언 {...}]
}
메서드는 추상, 일반 모두 가능하지만 프로퍼티는 오직 추상 메서드로만 선언해야 한다.
Pet 인터페이스 만들어 보기
코틀린에서는 상속, 구현 모두 콜론(:)을 통해 정의
게터를 구현한 프로퍼티
인터페이스에서는 프로퍼티에 값을 저장할 수없지만, val로 선언된 프로퍼티는 게터를 통해 필요한 내용을 구현할 수 있다.
여러 인터페이스를 이용한 다중 상속
인터페이스에서 동작의 이름이 같은 경우
super<인터페이스 이름>.메서드 이름()
형태로 구분할 수 있다.
인터페이스 위임
interface Nameable {
var name: String
}
class StaffName : Nameable {
override var name: String = "Sean"
}
class Work : Runnable { // 스레드 실행을 위한 인터페이스
override fun run( ){
println("work...")
}
}
// 1. 각 매개변수에 해당 인터페이스를 위임
class Person(name: Nameable, work: Runnable): Nameable by name, Runnable by work
fun main() {
val person = Person(StaffName(), Work()) // 2. 생성자를 사용해 객체 바로 전달
println(person.name) // 3. 여기서 StaffName 클래스의 name 접근
person.run() // 4. 여기서 Work 클래스의 run 접근
}
커피 제조기 만들어 보기
히터 Heater 인터페이스
전기 히터 ElectricHeater 클래스
펌프 Pump 클래스
열사이펀 Thermosiphon 클래스
커피 모듈 CoffeModule 인터페이스
드립 커피 모듈 MyDripCoffeeModule 클래스
커피 제조기 CoffeeMaker 클래스와 생성 테스트하기
데이터 전달을 위한 데이터 클래스
DTO(Data Transfer Object) - 구현 로직을 가지고 있지 않고 순수한 데이터 객체를 표현한다. 또한 게터세터, toString(), equals()등과같은 메서드를 가져야 하지만 코틀린은 자동으로 생성해준다.
데이터 클래스 조건
객체 디스트럭처링 하기
val (name, email) = cus1
val (_, email) = cu1 // 첫 번째 프로퍼티 제외
println("$name, $email")
val name2 = cus1.component1()
val email2 = cus1.component2()
내부 클래스 기법
1. 중첩 클래스 - 클래스 안에 또 다른 클래스가 정의되어 잇는 것.
2. 이너 클래스
// 정적 클래스처럼 사용한 코틀린의 중첩 클래스
class A {
class B { // 코틀린에서는 아무 키워드가 없는 클래스는 중첩 클래스이며 정적 클래스처럼 사용
... // 외부 클래스 A의 프로퍼티, 메서드에 접근할 수 없음.
}
}
// 코틀린의 이너 클래스
class A {
inner class B { // 자바와 달리 inner 키워드 필요
... // 외부 클래스 A의 필드에 접근 가능
}
}
중첩 클래스
중첩 클래스 사용하기
일반적으로 중첩 클래스는 바깥 클래스에 접근 할 수 없지만 Outer 클래스가 컴패니언 객체(static처럼 접근 가능)를 가지고 있을 때는 접근이 가능하다.
이너 클래스