Kotlin 객체 생성 - Kotlin gaegche saengseong

기본적인 클래스 구조 및 생성

  • class키워드로 클래스를 선언하며 기본으로 public가시성을 가진다.
  • 자바와 달리 객체를 생성시 new키워드를 사용하지 않는다.
Java
public class PersonJava {
    public static void main(String[] args) {
        PersonJava personJava = new PersonJava();
    }
}
Kotlin
class PersonKotlin {
    // empty class
}

fun main() {
    val personKotlin = PersonKotlin()
}

클래스 생성자

  • 하나의 클래스에는 주요 생성자보조 생성자를 가질 수 있다.
  • 주요 생성자는 클래스명 뒤에 위치한다.
class PersonKotlin constructor(name: String) {
    val name = name
}

fun main() {
    val p = PersonKotlin("jin")
    println(p.name) // jin
}
  • 가시성 제한자나 어노테이션이 없다면 constructor키워드는 생략 가능하다.
class PersonKotlin (name: String) {
    val name = name
}
  • 주요 생성자는 자바와 같이 생성자 코드 블록을 가질수 없으며 초기화 및 유효성 검사 코드는 init블록에서 가능하다.
class PersonKotlin (name: String) {
    val name = name
    init {
        // name이 isNotEmpty를 만족하지 않으면 IllegalArgumentException 발생
        require(name.trim().isNotEmpty()) { "require name" }
    }
}

fun main() {
    val p = PersonKotlin("") // IllegalArgumentException: require name
    val p1 = PersonKotlin("jin")
    println(p1.name) // jin
}
  • 주요 생성자에서는 프로퍼티를 선언 및 초기화를 간소화 할수 있게 해준다.
  • 주요 생성자에서 val로 생성시 읽기전용(only get)이며 var로 선언시 읽기 쓰기(read, write)가 가능하다.
class PersonKotlin (val name: String, var age: Int) {
}

fun main() {
    val p = PersonKotlin("jin", 31)
    // get
    println("name: ${p.name}, age: ${p.age}") // jin, 31

    // set
    // p.name = "park" // error
    p.age = 21

    println("name: ${p.name}, age: ${p.age}") // jin, 21
}
  • constructor키워드를 이용하여 보조 생성자를 만들 수 있다.
  • 멤버 변수(?)는 타입추론이 되지 않으니 타입을 명시해 주어야한다. (당연한건데... 몰랐음;;)
class PersonKotlin {
    val name: String
    constructor(name: String) {
        this.name = name
    }
}

fun main() {
    val p = PersonKotlin("jin")
    println(p.name) // jin
}
  • 주요 생성자에서 초기화 하지 않은 클래스의 모든 프로퍼티는 반드시 초기화를 해야한다. (자바의 경우에는 기본값을 초기화해줌)
class PersonKotlin(age: Int) {
    val age: Int = age // ok
}

---
// 클래스명 옆에 괄호를 붙이지 않고 construcotr사용시 constructor자체가
// 주요 생성자가 되어 바로 초기화 시켜줄수 있는것으로 보임
class PersonKotlin {
    val age: Int
    
    constructor(age: Int) {
        this.age = age // ok
    }
}

---
// 아래의 경우 비어있는 주요 생성자가 존재하므로
// 보조 생성자에서 age초기화를 못함.
// 여기서는 age의 초기화를 해주어야한다.
class PersonKotlin() {
    val age: Int // X
    // val age: Int = 0 // O
    
    constructor(age: Int): this() {
        this.age = age // error
    }
}
  • 주요 생성자와 보조 생성자를 혼합하여 사용할 경우 주요 생성자는 반드시 호출해야한다.
class PersonKotlin(val name: String) {
    // 주요 생성자에 없는것은 임의로 초기화 시켜줘야함.
    var age: Int = 0

    constructor(name: String, age: Int): this(name) {
        this.age = age
    }
}

fun main() {
    val p = PersonKotlin("jin", 31)
    println("name: ${p.name}, age: ${p.age}") // jin, 31
}
  • 생성자가 가시성 제한자를 가진다면 constructor를 명시해주어야 한다.
class PersonKotlin private constructor() {
}

fun main() {
    val p = PersonKotlin() // error - private constructor
}

출처

https://medium.com/@sket8993/kotlin-%EC%83%9D%EC%84%B1%EC%9E%90-%EC%B4%88%EA%B0%84%EB%8B%A8-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-b8a61df6fe6
https://tourspace.tistory.com/107

코틀린(Kotlin) 16. 클래스와 객체(생성자)

Kotlin 객체 생성 - Kotlin gaegche saengseong
태호2019. 2. 19. 20:00

클래스)

class 키워드를 사용하여 선언하며 멤버 속성과 멤버 함수를 가질 수 있다.

class 클래스이름 {멤버들 구현}

멤버를 가지고 있지 않으면 중괄호를 생략 가능하다.

class 클래스이름

기본 생성자)

코틀린에서 기본 생성자는 클래스 헤더 안에 정의한다.

class 클래스이름(속성) {}

예시로 Car 클래스를 정의해보겠다.

class Car(val engine:String, val tire:String){}

위와 같은 형식을 사용하면 Car 클래스의 속성도 자동으로 생성하고 초기화해 준다.

Car 클래스의 객체를 생성할 때 engine과 tire 즉, Car 클래스의 속성을 초기화 시켜줄 수 있다.

사실 위의 예제 코드에서 constructor 키워드가 생략되었다.

class Car constructor(val engine:String, val tire:String){}

기본 생성자에서 constructor 키워드를 생략할 수 있다.

단, 생성자를 private 제한자로 사용할 때는 constructor 키워드를 지정해야 한다.

class Car private constructor(val engine:String, val tire:String){}

Car 클래스의 생성자 인자와 클래스 속성을 별개로 선언하는 방법도 있다.

class Car (eng:String, t:String)

{

val engine = eng

val tire = t

}

Car 클래스의 생성자 인자들이 val, var처럼 변수로 선언하지 않고 함수의 인자처럼 선언되어 있다.

인자 값으로 받아온 변수들을 다시 클래스의 속성에 저장시키는 방법이다.

초기화 블록을 사용하여 클래스의 속성을 초기화할 수 있다.

초기화 블록을 initialization block 이라고 하며 키워드로 init 이다.

class Car (eng:String, t:String)

{

var engine: String

var tire: String

init {

engine = eng

tire = t

}

}

class Car (engine:String, tire:String)

{

var engine: String

var tire: String

init {

this.engine = engine

this.tire = tire

}

}

초기화 블록은 객체 생성 시에 자동으로 실행된다.

우측에 this 키워드는 그 클래스의 인스턴스 참조를 나타낸다. 즉, 위의 코드에서 this는 Car의 인스턴스의 engine, tire 속성을 가리킨다.

초기화 블록은 생성자 인자로 전달되는 값을 검사하고 초기화하는데 유용하다.

함수에서 사용했던 지명 인자를 클래스의 기본 생성자에서도 사용 가능하다.

(지명 인자) https://blog.naver.com/lth9036/221468967973

보조 생성자)

클래스의 몸체 안에 정의하는 생성자이다.

class 클래스이름

{

constructor(인자){초기화}

}

위의 코드를 보조 생성자로 구현해보자.

class Car

{

var engine: String

var tire: String

var door: Int

constructor(engine:String, tire:String, door:Int=4)

{

this.engine = engine

this.tire = tire

this.door = door+1//적재함 문을 더해준다.

}

}

클래스의 중괄호 내부에서 구현된 생성자이다. 이를 보조 생성자라고 하는데 보조 생성자는 여러 개를 정의할 수 있다. 즉, 코틀린에서는 여러 개의 오버로딩된 보조 생성자를 정의할 수 있다.

오버로딩된 보조 생성자를 정의한 코드를 보자.

class Car

{

var engine: String

var tire: String

var door: Int

constructor(engine: String) : this(engine,door=2) {}

constructor(engine: String="누우", tire: String="한국타이어", door: Int =4)

{

this.engine = engine

this.tire = tire

this.door = door+1//적재함 문을 더해준다.

}

}

한 개의 인자를 받은 보조 생성자는 this() 를 사용해서 다른 보조 생성자를 호출한다. (this()를 해당 몸체가 아닌 반환 타입으로 선언해야 한다)

메인 함수에서 Car 클래스의 객체를 생성하고 객체의 속성을 출력해보자.

fun main() {

val MyCar = Car("GDI")

val YourCar = Car()

println("MyCar.engine = ${MyCar.engine}")

println("MyCar.tire = ${MyCar.tire}")

println("MyCar.door = ${MyCar.door}")

println("YourCar.engine = ${YourCar.engine}")

println("YourCar.tire = ${YourCar.tire}")

println("YourCar.door = ${YourCar.door}")

}

class Car

{

var engine: String

var tire: String

var door: Int

constructor(engine: String) : this(engine,door=2) {}

constructor(engine: String= "누우", tire: String="한국타이어", door: Int=4)

{

this.engine = engine

this.tire = tire

this.door = door+1//적재함 문을 더해준다.

}

}

MyCar.engine = GDI

MyCar.tire = 한국타이어

MyCar.door =3

YourCar.engine = 누우

YourCar.tire = 한국타이어

YourCar.door =5

위의 코드에서 YourCar 객체는 기본 생성자로 생성했는데 인자가 3개인 보조 생성자로 생성되었다. 그 이유는 인자를 모두 초기화한 생성자이므로 자동으로 찾아 생성한 것이다.

만약 기본 생성자와 보조 생성자를 모두 정의하지 않으면 인자가 없는 기본 생성자를 컴파일러가 자동으로 생성해 준다.