2024-06-21
This commit is contained in:
287
Writerside/topics/Class.md
Normal file
287
Writerside/topics/Class.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# 객체
|
||||
|
||||
다음과 같이 클래스를 선언합니다.
|
||||
|
||||
```kotlin
|
||||
class Shape {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
바디가 없는 클래스도 있습니다.
|
||||
|
||||
```kotlin
|
||||
class Empty
|
||||
```
|
||||
|
||||
## 생성자
|
||||
|
||||
### 기본 생성자
|
||||
|
||||
기본 생성자는 `constructor`를 사용해서 클래스 헤더 부분에 정의합니다.
|
||||
|
||||
```kotlin
|
||||
class Person constructor(name: String) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
기본 생성자에 별다른 어노테이션이나 접근한정자를 명시할 필요가 없는 경우에는 `constructor` 키워드를 생략할 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
class Person (name: String) {
|
||||
// ...
|
||||
}
|
||||
|
||||
class Person public constructor(name: String) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
기본 생성자의 경우, 별도의 초기화 로직을 정의할 수 없는 대신, 초기화 블록을 사용할 수 있습니다. 초기화 블록은 `init`을 사용해서 정의하며, 여러 개의 초기화 블록이 있을 경우, 순서대로 실행됩니다. 기본 생성자에 선언된 매개 변수는 초기화 블록에서 사용할 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
class Person (name: String) {
|
||||
init {
|
||||
// initializer block ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 보조 생성자
|
||||
|
||||
두 번째 생성자부터는 클래스 바디에 정의합니다. 기본 생성자가 정의되어 있는 경우에는 기본 생성자로부터 또는 다른 보조 생성자로부터 값을 위임 받아야 합니다.
|
||||
|
||||
기본 생성자가 없는 경우라도, 암묵적으로 위임 처리가 진행되며 초기화 블록도 실행됩니다.
|
||||
|
||||
```kotlin
|
||||
class Person (name: String) {
|
||||
init {
|
||||
// initializer block ...
|
||||
}
|
||||
constructor (name: String, age: Int) : this(name) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
기본 생성자도 보조 생성자도 정의되지 않은 클래스의 경우, 매개 변수가 없는 기본 생성자가 자동으로 생성되며, 자동으로 만들어진 생성자는 public의 접근 권한으로 지정됩니다.
|
||||
|
||||
## 객체의 인스턴스화
|
||||
|
||||
> 코틀린에는 `new` 키워드가 없습니다.
|
||||
|
||||
```kotlin
|
||||
val charlie = Person("Charlie")
|
||||
```
|
||||
|
||||
## 프로퍼티
|
||||
|
||||
`var` 또는 `val`을 사용해서 클래스의 프로퍼티를 선언합니다.
|
||||
|
||||
```kotlin
|
||||
class Person {
|
||||
val name: String
|
||||
var age: Int
|
||||
}
|
||||
```
|
||||
|
||||
프로퍼티의 겟터와 셋터를 지정할 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
class SomeClass {
|
||||
var someProperty: String
|
||||
get() = this.toString()
|
||||
set(value) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
겟터와 셋터에 접근한정자를 지정하거나 어노테이션을 지정하는 경우에 다음과 같이 할 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
var someProperty: String = "abcd"
|
||||
private set // 셋터는 기본 구현을 사용하며, 접근은 private으로 제한
|
||||
```
|
||||
|
||||
### 필드
|
||||
|
||||
`field`는 프로퍼티의 값을 임시로 저장해두는 공간입니다. `field`는 프로퍼티의 접근자에서만 사용할 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
var counter = 0
|
||||
set(value) {
|
||||
if (value >=0) field = value
|
||||
// counter = value 라고 하면 안됩니다.
|
||||
}
|
||||
```
|
||||
|
||||
### 컴파일 타임 상수
|
||||
|
||||
컴파일 타임에만 사용되는 상수에는 `const` 키워드를 붙여서 컴파일 타임 상수로 만듭니다.
|
||||
|
||||
```kotlin
|
||||
const val MY_VALUE: String = "..."
|
||||
```
|
||||
|
||||
### 지연 초기화 프로퍼티 또는 변수
|
||||
|
||||
```kotlin
|
||||
lateinit var subject: Subject
|
||||
```
|
||||
|
||||
## 추상 클래스
|
||||
|
||||
추상 클래스는 `abstract`를 사용해서 정의합니다. 추상 클래스는 상속을 전제로 하므로 `open`을 명시할 필요가 없습니다.
|
||||
|
||||
오버라이드하는 함수 앞에는 `override` 키워드를 붙입니다.
|
||||
|
||||
```kotlin
|
||||
abstract class Shape {
|
||||
abstract fun draw()
|
||||
}
|
||||
|
||||
class Rectangle : Shape() {
|
||||
override fun draw(){
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
추상 클래스가 아닌 클래스를 상속하는 추상 클래스도 만들 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
open class Shape {
|
||||
open fun draw(){
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SomeShape : Shape() {
|
||||
abstract override fun draw()
|
||||
}
|
||||
```
|
||||
|
||||
## 인터페이스
|
||||
|
||||
인터페이스는 구현된 메서드를 가질 수도 있으며, 프로퍼티를 가질 수도 있습니다.
|
||||
|
||||
```kotlin
|
||||
interface MyInterface {
|
||||
val prop1: Int // 추상 프로퍼티
|
||||
val prop2: String // 겟터가 구현된 프로퍼티
|
||||
get() = "foo"
|
||||
fun bar()
|
||||
fun foo() {
|
||||
// 바디를 가질 수도 있습니다.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 다중 상속시 충돌의 해결
|
||||
|
||||
```kotlin
|
||||
interface A {
|
||||
fun foo() { print("A") }
|
||||
fun bar()
|
||||
}
|
||||
interface B {
|
||||
fun foo() { print("B") }
|
||||
fun bar()
|
||||
}
|
||||
|
||||
class C : A, B {
|
||||
override fun foo() {
|
||||
super<A>.foo()
|
||||
super<B>.foo()
|
||||
}
|
||||
override fun bar(){
|
||||
print("C")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 상속
|
||||
|
||||
클래스의 상속은 `:`을 사용해서 표현합니다.
|
||||
|
||||
클래스는 기본적으로 `final`이므로 상속 가능하게 하려면 클래스 선언 앞에 `open`을 지정해야 합니다.
|
||||
|
||||
```kotlin
|
||||
open class Shape
|
||||
|
||||
class Rectangle(var height: Double, var length: Double): Shape(){
|
||||
var perimeter = (height + length) * 2
|
||||
}
|
||||
```
|
||||
|
||||
```kotlin
|
||||
open class Base(p: Int)
|
||||
|
||||
class Derived(p: INt) : Base(p)
|
||||
```
|
||||
|
||||
만일, 클래스에 기본 생성자가 없다면 각각의 보조 생성자에서 `super`를 통해서 호출해야 합니다.
|
||||
|
||||
```kotlin
|
||||
class Dog : Animal {
|
||||
constructor(name: String) : super(name)
|
||||
constructor(name: String, age: Int) : super(name, age)
|
||||
}
|
||||
```
|
||||
|
||||
상속 가능한 클래스와 오버라이드 가능한 메서드 앞에는 `open`을 붙이니다. 그리고, 오버라이드 하는 메서드 앞에는 `override`를 붙입니다.
|
||||
|
||||
오버라이드 한 메서드는 `open`상태이므로, 자식 클래스에서 오버라이드를 제한하려면 `final`을 붙여야 합니다.
|
||||
|
||||
```kotlin
|
||||
open class Rectangle() : Shape() {
|
||||
final override fun draw() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
메서드와 마찬가지 방식으로 프로퍼티도 오버라이드할 수 있습니다.
|
||||
|
||||
```kotlin
|
||||
open class Shape {
|
||||
open val vertexCount: Int = 0
|
||||
}
|
||||
|
||||
class Rectangle : Shape() {
|
||||
override val vertexCount = 4
|
||||
}
|
||||
```
|
||||
|
||||
## Data 클래스
|
||||
|
||||
```kotlin
|
||||
data class User(val name: String, val age:Int)
|
||||
```
|
||||
|
||||
## Sealed 클래스
|
||||
|
||||
```kotlin
|
||||
sealed interface Error
|
||||
sealed class IOError(): Error
|
||||
```
|
||||
|
||||
## Inner 클래스
|
||||
|
||||
```kotlin
|
||||
class Outer {
|
||||
private val bar: Int = 1
|
||||
inner class Inner {
|
||||
fun foo() = bar
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 인라인 클래스
|
||||
|
||||
```kotlin
|
||||
@JvmInline
|
||||
value class Password(private val s: String)
|
||||
```
|
||||
Reference in New Issue
Block a user