클래스
- 클래스 생성자는 클래스 이름 옆에 위치
- 주 생성자라고 명칭하며 추가 생성자 작성 가능
- 일반적인 상황에서는 기본값 파라미터 사용을 권장
- 클래스 정의 시 프로퍼티 항목에 var/val 키워드를 사용하면 getter/setter 함수는 자동 생성
- Java 클래스를 사용할 때도 동일하게 사용 가능
- 클래스 블록 내
init
키워드를 사용해 클래스 생성 시 로직 작성 가능
- 함수를 클래스 프로퍼티와 같이 정의하여 사용 가능
- 필드 프로퍼티의 custom getter/setter를 사용할 때
field
(backing field) 키워드를 사용하여 재정의 가능
class Person constructor(name: String, age: Int) {
val name: String = name
var age: Int = age
}
class Person(val name: String, var age: Int)
val person = Person("abc", 10)
println(person.name)
person.age = 20
println(person.age)
class Person(val name: String, var age: Int) {
init {
if (age <= 0) {
...
}
}
constructor(name: String) : this(name, 1) {
println("부 생성자")
}
fun isAdult(): Boolean {
return this.age >= 20
}
val isAdult: Boolean
get() {
return this.age >= 20
}
val uppercaseName: String = name
get(): String = field.uppercase()
var name = name
set(newValue) {
field = newValue.uppercase()
}
}
상속 및 구현
extends
, implement
키워드 대신 클래스 정의 코드 뒤 : SuperClass(생성자)
형식으로 입력함
- 함수 재정의 시
override
키워드 명시해야 함
- 하위 클래스에서 상위 클래스의 프로퍼티를 재정의하려면 상위 클래스에서 해당 프로퍼티를
open
키워드로 정의해야 함
- 클래스 프로퍼티에는 기본적으로
final
키워드가 사용됨
- 인터페이스의 프로퍼리를 재정의할 때는
field
키워드 없이 재정의 가능
- 상위 클래스를 설계할 때 생성자 혹은 초기화 블록에 사용되는 프로퍼티에
open
설정을 하면 안 됨
- 동작 순서 상 하위 클래스에서 정의되기 전에 호출하면 의도한 값이 설정되지 않을 수 있음
class Animal(
protected val species: String,
protected open val legCount: int
) {
abstract fun move()
}
interface Swimmable {
val swimScore: Int
fun act() {
println("...")
}
}
interface Flyable {
fun act() {
println("...")
}
}
class Cat(species: String)
: Animal(species, 4) {
override fun move() {
println("...")
}
}
class Penguin(
species: String
) : Animal(species, 2), Swimmable, Flyable {
private val wingCount: Int = 2
override fun move() {
println("...")
}
override val legCount: Int
get() = super.legCount + this.wingCount
override fun act() {
super<Swimmable>.act()
super<Flyable>.act()
}
override val swimScore: Int
get() = super.swimScore
}
접근 제어
기본 접근 제어자
- Java -
default
- Kotlin -
public
package
- Java - 같은 패키지 혹은 하위 클래스에서만 접근 가능
- Kotlin - 선언된 클래스 또는 하위 클래스에서만 접근 가능
default
- Java - 같은 패키지에서만 접근 가능
- Kotlin -
internal
로 명칭 변경, 같은 모듈에서만 접근 가능
class Car(
internal val name: String,
private var owner: String,
_price: Int
) {
var price = _price
private set
}
Static
- Kotlin에는
static
키워드가 없음
companion object
키워드를 사용해 클래스 내부의 static
과 같은 속성을 가진 객체 생성
class
키워드 대신 object
키워드를 사용해 Singleton 객체 생성
class Person(
val name: String,
var age: Int
) {
companion object Hospital {
const val MIN_AGE = 0
@JvmStatic
fun newBaby(name: String): Person {
return Person(name, MIN_AGE)
}
}
}
public static void callKotlinStatic() {
Person.Hospital.newBaby("");
Person.newBaby("");
}
익명 클래스
interface SomeInterface {
void actionA();
void actionB();
}
new SomeInterface() {
@Override
void actionA() {
...
}
@Override
void actionB() {
...
}
}
(object : SomeInterface) {
override fun actionA() {
...
}
override fun actionB() {
...
}
}
클래스 중첩
- Java에서는 내부 클래스를
static
으로 정의하는 것을 권장함
- Kotlin은
static
키워드를 사용할 수 없기 때문에 기본적으로 static
클래스와 같이 설정됨
static
이 아닌 내부 클래스를 정의하려면 inner
키워드로 정의
class House(
var address: String
var livingRoom: LivingRoom
) {
inner class LivingRoom(
area: Double
) {
val address: String
get() = this@House.address
}
}
클래스 제어
data class
- equals
, toString()
, hashcode
함수를 자동으로 만들어주는 클래스 정의
enum class
에 대해 when
분기 처리를할 때 else
를 작성하지 않아도 무관
sealed class
를 사용하여 상속/구현 가능한 클래스를 제한할 수 있음