[Kotlin] 클래스의 구조, 생성자

zirryo·2023년 5월 16일
0

⚡️ STUDY

목록 보기
15/15
post-thumbnail




💬 1. 클래스 Class



1-1 클래스란?

객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀.

  • class의 어원은 classification(분류).
  • 객체를 정의하기 위한 메소드와 변수로 구성된다.



1-2 클래스의 선언

Kotlin의 클래스는 class 키워드를 사용하여 선언한다.

// 클래스 선언
class Car { /*...클래스의 본문...*/ } 


// 헤더와 본문이 생략된 경우
class Empty 
  • 클래스 선언은 클래스의 이름, 클래스 헤더(유형 매개변수, 기본 생성자 및 기타 항목 지정) 및 중괄호로 묶인 클래스 본문으로 구성된다.
  • 헤더본문은 모두 선택 사항으로, 클래스에 본문이 없으면 중괄호를 생략할 수 있다.



1-3 클래스와 인스턴스

인스턴스는 클래스를 통해 만들어낸 서로 다른 속성의 객체이다.

  • 추상적인 개념인 클래스에서 실제 객체를 생성하는 것을 인스턴스화(instantiation) 라고 한다.
  • 객체 지향 언어의 관점에서는 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부른다.
  • 자바와는 달리 new 키워드를 사용하지 않는다.

인스턴스를 생성하려면, 일반 함수를 호출하듯 클래스의 생성자를 호출하면 된다.

class Car(val name: String, var price: Int)

class Music

val car1 = Car("cayenne", 15000)
val car2 = Car("santaFe", 3500)

val music1 = Music()
val music2 = Music()



1-4 클래스의 멤버

클래스는 다음과 같은 것들을 포함할 수 있으며, 이를 클래스의 멤버라고 한다.

  • Constructors and initializer blocks 생성자와 초기화 블록
  • Functions 함수
  • Properties 속성
  • Nested and inner classes 중첩 및 내부 클래스
  • Object declarations 객체의 선언



1-5 클래스의 사용

변수명.속성명, 변수명.함수명 등 의 형태로 클래스의 멤버를 사용할 수 있다.

class Car(var name: String, var price: Int) {
    fun introduce() {
        println("이 차는 $name 이고, 가격은 $price 만원 입니다.")
    }

    fun discount() {
        price -= 1000
    }
}

fun main() {
    val car1 = Car("cayenne", 15000)
    val car2 = Car("santaFe", 3500)

    car1.name = "cayenne coupe"
    car2.price = 3700

    car1.discount()
    car1.introduce()
    car2.introduce()
}




💬 2. 생성자 Constructor



2-1 생성자란?

객체 지향 프로그래밍에서 객체가 생성될 때 초기화시켜주는 함수를 의미한다.

class Constructor() { /*...*/ } 
  • 필요에 따라 객체 내 데이터에 특정한 값을 입력하기도 한다.
  • 생성자는 자료형을 갖지 않는다. void 도 아니다.
  • Kotlin의 클래스는 기본 생성자(primary constructor) 와 하나 이상의 보조 생성자(secondary constructors)를 가질 수 있다.



2-2 init

파라미터나 반환형이 없는 특수한 함수로, 생성자를 통해 인스턴스가 만들어 질 때 호출된다.

class Car(var name: String, var brand: String) {
    init {
        println("${this.brand}의 차 ${this.name}이 생성되었습니다.")
    }
}

fun main() {
    val car1 = Car("cayenne", "porsche")
    val car2 = Car("santaFe", "hyundai")
}

  • this : 인스턴스 자신의 속성이나 함수를 호출하기 위해 클래스 내부에서 사용되는 키워드.



2-3 기본 생성자

클래스 헤더의 일부이며, 클래스 이름 뒤에 작성한다.

class Person constructor(firstName: String) { /*...*/ }

class Person(firstName: String) { /*...*/ }
  • 기본 생성자에 annotations, visibility modifiers가 없으면 constructor 키워드를 생략할 수 있다.
    • visibility modifiers : private, protected, internal, public
    • default 는 public 이다.
  • 기본 생성자는 어떤 코드도 포함할 수 없다.
  • 초기화 코드는 init 키워드가 있는 초기화 블록(initializer blocks) 에 배치할 수 있다.
  • 일반 속성과 마찬가지로, 기본 생성자에 선언된 속성은 var 혹은 val 이다.

기본 생성자의 파라미터는 초기화 블록과 클래스 본문에 선언된 속성의 이니셜라이저에서 사용할 수 있다.

class Car(var name: String, var brand: String) {
    init {
        println("${this.brand}의 차 ${this.name}이 생성되었습니다.")
    }
    val uppercaseBrand = brand.uppercase()
}

fun main() {
    val myCar = Car("santaFe", "hyundai")
    println(myCar.uppercaseBrand)
}


// 출력
hyundai의 차 santaFe이 생성되었습니다.
HYUNDAI

기본 생성자는 클래스 속성의 기본값을 포함할 수 있다.

class Car(var name: String, var brand: String = "kia") {
    init {
        println("${this.brand}의 차 ${this.name}가 생성되었습니다.")
    }
    val uppercaseBrand = brand.uppercase()
}

fun main() {
    val myCar = Car("EV6")
    println(myCar.uppercaseBrand)

    val secondCar = Car("AVANTE", "hyundai")
    println(secondCar.uppercaseBrand)
}


// 출력
kia의 차 EV6가 생성되었습니다.
KIA
hyundai의 차 AVANTE가 생성되었습니다.
HYUNDAI



2-4 보조 생성자

기본 생성자와 다른 형태의 생성자를 제공하여, 인스턴스 생성시 편의를 제공하거나 추가적인 구문을 수행할 수 있도록 한다.

class Car(var name: String, var brand: String) {
    init {
        println("초기화 블록: ${this.brand}의 차 ${this.name} 생성되었습니다.")
    }
    constructor(name: String, modelYear: Int) : this(name, "kia") {
        println("보조생성자1: $modelYear ${this.name} 입니다.")
    }
    constructor() : this("알수없음", "알수없음") {
        println("보조생성자2: 차량의 정보를 다시 입력해주세요.")
    }
    constructor(modelYear: Int) : this("k5", modelYear) {
        println("보조생성자3: 연식을 이용하여 차량을 생성했습니다.")
    }
}

fun main() {
    val car1 = Car("AVANTE", "hyundai")
    val car2 = Car("EV6", 2023)
    val car3 = Car()
    val car4 = Car(2018)
}


// 출력
초기화 블록: hyundai의 차 AVANTE 생성되었습니다. // car1
초기화 블록: kia의 차 EV6 생성되었습니다. //car2
보조생성자1: 2023 EV6 입니다. // car2
초기화 블록: 알수없음의 차 알수없음 생성되었습니다. // car3
보조생성자2: 차량의 정보를 다시 입력해주세요. // car3
초기화 블록: kia의 차 k5 생성되었습니다. // car4
보조생성자1: 2018 k5 입니다. // car4
보조생성자3: 연식을 이용하여 차량을 생성했습니다. // car4
  • constructor 키워드를 통해 보조 생성자를 선언한다.
  • 클래스에 기본 생성자가 있는 경우 각 보조 생성자는 직접 또는 다른 보조 생성자를 통해 간접적으로 기본 생성자에게 위임해야 한다.

동일한 클래스의 다른 생성자에 대한 위임은 this 키워드를 사용한다.

  • 보조생성자1 에서는 this(name, "kia") 를 통해 기본 생성자 에게 위임.
  • 보조생성자2 에서는 this("알수없음", "알수없음") 를 통해 기본 생성자 에게 위임.
  • 보조생성자3 에서는 this("k5", modelYear) 를 통해 보조생성자1 에게 위임.
  • 기본 생성자에 대한 위임은 보조 생성자의 첫 번째 문에 액세스하는 순간에 발생하므로 모든 초기화 블록 및 속성의 초기화는 보조 생성자의 본문보다 먼저 실행된다.

클래스에 기본 생성자가 없더라도 위임은 암시적으로 발생하며 이니셜라이저 블록 또한 실행된다.

class Constructors {
    init {
        println("Init block")
    }

    constructor(i: Int) {
        println("Constructor $i")
    }
}

fun main() {
	val a = Constructors(5)
}


// 출력
Init block
Constructor 5
  • 초기화 블록의 코드는 기본 생성자의 일부이다.




🔗 reference1
🔗 reference2

0개의 댓글