티스토리 뷰
728x90
- 클래스 구조
class Person {
var firstName: String = ""
var familyName: String = ""
var age: Int = 0
fun fullName() = "$firstName $familyName"
fun showMe() {
println("${fullName()}: $age")
}
}
- 위 클래스의 인스턴스마다 firstName, familyName. age라는 프로퍼티와 fullName(), showMe()라는 함수가 포함된다.
cf) 파일명을 public 클래스의 이름과 동일하게 만들지 않아도 된다.
한 파일에 여러 public 클래스가 존재할 수 있다.
2. 생성자
- 주생성자
class Person(firstName: String, familyName: String) {
val fullName = "$firstName $familyName"
init {
println("Created new Person instance: $fullName")
}
}
fun main() {
val person = Person("John", "Doe")
println(person.fullName)
}
-
- 주생성자 파라미터
- 클래스 헤더의 파라미터 목록.
- 인스턴스 생성시 클래스의 파라미터에 전달된다.
- 프로퍼티 초기화나 init 블록 내에서만 사용 가능하다.
- 디폴트 값과 vararg를 사용할 수 있다.
- 주생성자 파라미터
-
- init 블록
- 주생성자가 호출될 때마다 수행되는 초기화 블록.
- 블록 안에서 프로퍼티를 초기화할 수 있다.
- 여러개 사용할 수 있고 return문이 들어갈 수 없다.
- 주생성자 실행 후 모든 프로퍼티가 초기화되어야 한다.
- 주생성자에 접근 제한자를 지정하기 위해서는 constructor 키워드를 명시해야 한다.
- ex) class Person protected constructor()
- init 블록
class Person(val firstName: String, val familyName: String) {
val fullName = "$firstName $familyName" // 생성자 파라미터
init {
println("Created new Person instance: $fullName") // 생성자 파라미터
}
fun printFirstName() {
println(firstName) // 멤버 프로퍼티
}
}
-
- 생성자 파라미터 → 멤버 프로퍼티
- 생성자 파라미터 앞에 val/var 키워드를 붙이면, 생성자 파라미터와 이름이 같고 생성자 파라미터로부터 초기화되는 프로퍼티가 정의된다.
- 프로퍼티 초기화나 init 블록에서 참조: 생성자 파라미터
- 다른 위치에서 참조: 프로퍼티
- 생성자 파라미터 → 멤버 프로퍼티
class Person(val firstName: String, val familyName: String)
- 이를 이용해 본문이 없는 클래스를 정의할 수 있다.
- 부생성자
-
- 인스턴스를 여러 방법으로 초기화하고 싶은 경우 사용할 수 있다.
- constructor 키워드를 사용해서 선언한다.
- 부생성자를 실행하기 전에 프로퍼티 초기화와 init 블록을 실행한다.
- return을 사용할 수 있다.
- 부생성자의 파라미터 목록에는 val/var 키워드를 사용할 수 없다. (내부에서는 불변 변수로 사용됨)
class Person {
val fullName: String
constructor(firstName: String, familyName: String):
this("$firstName $familyName")
constructor(fullName: String) {
this.fullName = fullName
}
}
-
- 클래스에 주생성자가 없는 경우
- 다른 부생성자를 위임하여 프로퍼티를 초기화할 수 있다.
- 클래스에 주생성자가 없는 경우
class Person(val fullName: String) {
constructor(firstName: String, familyName: String):
this("$firstName $familyName")
}
-
- 클래스에 주생성자가 있는 경우
- 모든 부생성자는 주생성자에게 위임 하거나 다른 부생성자에게 위임해야 한다.
- 클래스에 주생성자가 있는 경우
3. 내포된 클래스 (nested class)
- 클래스 내부에서 다른 클래스를 정의할 수 있다.
class Person(private val id: Id) {
class Id(private val name: String) {
fun nameSake(person: Person) = person.id.name == name // 가능
}
fun showMe() = println("${id.name}") // error
}
- 바깥쪽 클래스에서 내포된 클래스의 private 멤버에 접근할 수 없다.
- 클래스 밖에서는 바깥쪽 클래스명.내포된 클래스명 으로 사용한다.
- ex) Person.Id("John")
- 내부 클래스 (inner class)
class Person(val firstName: String, val familyName: String) {
inner class Possession(val description: String) {
fun showOwner() = println(fullName()) // println(this@Person.fullName())
}
fun fullName() = "$firstName $familyName"
}
fun main() {
val person = Person("John", "Doe")
val wallet = person.Possession("Wallet")
wallet.showOwner()
}
-
- 내포된 클래스에 inner를 붙이면 바깥쪽 클래스의 인스턴스에 접근할 수 있다.
- 클래스 밖에서는 바깥쪽 클래스명이 아닌 인스턴스명.내부 클래스명 으로 사용한다.
- 내부 클래스 내에서 외부 클래스의 인스턴스를 가리켜야 한다면 this@외부 클래스명 으로 사용한다.
- ex) this@Person
- 읿반적으로 this는 항상 가장 내부 클래스의 인스턴스를 가리킨다.
4. 지역 클래스
fun main() {
var x = 1
class Counter {
fun increment() {
x++
}
}
Counter().increment()
println(x) // 2
}
- 함수 내에서 클래스를 정의할 수 있다.
- 지역 클래스는 자신을 둘러싼 코드 블록 안에서만 쓰일 수 있다. (→ 접근 제한자를 붙일 수 없다.)
- 자신을 둘러싼 코드 블록의 값을 접근하고 변경할 수 있다.
- 지역 클래스의 내포된 클래스는 항상 inner 클래스여야 한다.
5. nested class ↔ inner class
- nested class
- 외부 클래스와 독립적으로 존재한다. 외부 클래스의 인스턴스와 관련이 없다.
- 외부 클래스의 멤버에 접근할 수 없다.
- 해당 클래스의 인스턴스를 생성할 때 메모리에 독립적인 공간이 할당된다.
- inner class
- 외부 클래스의 인스턴스와 연관되어 있다.
- 외부 클래스의 멤버 함수나 프로퍼티에 접근할 수 있다.
- 외부 클래스의 인스턴스가 생성되어야만 inner class의 인스턴스를 생성할 수 있다.
- inner class의 인스턴스는 외부 클래스의 인스턴스와 연결된 메모리 주소를 가진다. (외부 클래스의 참조를 가짐)
- 외부 클래스가 삭제되더라도 inner class가 남아있다면 메모리 누수가 발생할 수 있다.
- 지역 클래스 내에서 nested class는 선언할 수 없고 inner class만 가능한 이유
- 지역 클래스는 자신을 둘러싼 불록의 값에 접근하거나 값을 변경할 수 있다.
- nested class는 외부 클래스의 값에 접근할 수 없는데, 지역 클래스 안에서는 접근이 가능하다면 가시성 규칙에 어긋난다.
728x90
'app > kotlin' 카테고리의 다른 글
[kotlin/코틀린] 프로퍼티 (0) | 2023.06.22 |
---|---|
[kotlin/코틀린] 널 가능성 (0) | 2023.06.22 |
[kotlin/코틀린] 기초 문법 (문자열, 배열, 함수) (0) | 2023.06.22 |
[kotlin/코틀린] 기초 문법 (변수, 타입) (0) | 2023.06.22 |
[kotlin/코틀린] 기초 문법 (조건문, 루프, 예외 처리) (0) | 2023.06.22 |