class란?
객체 지향 프로그래밍(OOP)에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀(template)이다. 객체를 정의하기 위한 메소드와 변수로 구성된다. (출처 : 위키백과)
Kotlin에서 클래스를 만들 때는 class 키워드 뒤에 클래스 이름을 적고, {} 안에 원하는 내용을 적어주면 된다.
이때 body가 없는 경우에는 중괄호를 생략할 수 있다. ex) class Person{}
Constructor
해당 클래스의 인스턴스를 실제로 생성하는(초기화하는) 방식을 정의하는 특수한 메서드.
1. primary constructor
클래스 이름과 body 사이에 받을 값을 선언한다.
class MyClass(name: String, age: Int) {
private val name = name
var age = age
}
이때 대부분의 경우에는 받은 값을 그대로 클래스 속성에 넣어주게 될텐데, 이 경우에는 괄호 안에서 속성 선언까지 끝낼 수 있다. 아래 코드는 위 코드와 동일한 내용을 담고있다.
class MyClass( private val name: String, var age: Int )
굳이 constructor 키워드를 쓰겠다면 아래처럼 할 수도 있다.
내가 생각할 때 primary constructor를 가장 길게 쓸 수 있는 방법으로 보인다.
class MyClass {
private val name: String
var age: Int
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
}
변수에 값을 할당하는 것 외에 다른 동작( ex : for loop의 사용 등)이 없다면 init이 없어도 되지만, 한 줄로 끝나지 않는 작업일 경우에는 init 블럭 안에서 처리해줘야한다.
class Simple(
val name: String,
var age: Int = 0, // 인자가 여럿일 때 trailing comma로 추가 및 변경 쉽게할 수 있음
) {
val customerKey = name.uppercase() // 메서드 호출 정도는 init 불필요
}
class Complicate(
val name: String,
var age: Int,
) {
val introduction: String // init 블럭에서 정의된다면 late init이 아니다.
init {
val schoolType = if (age > 19) {"대학생"} else {"고등학생"}
introduction = "안녕하세요 저는 $name 이고, $age 살 $schoolType 입니다."
}
}
예시에서는 init 블럭이 하나지만, init은 클래스 하나에 여러개 쓸 수 있다. 이때 각 블럭은 위에서부터 순서대로 실행된다.
Tip ) 외부에서 객체를 생성하지 못하게 하는 방법 - private constructor
위에서 본 예시에서는 contructor를 생략할 수 있었지만, 이렇게 private으로 지정해줄 때는 반드시 붙여줘야한다.
class Single private constructor() {}
2. secondary constructor
primary constructor에서 받는 인자 외의 다른 형태로도 객체를 초기화하고 싶을 수 있다.
이럴 때 constructor 키워드를 이용해서 secondary constructor를 만들어주면 된다.
secondary constructor는 : this()로 primary constructor를 호출해서 원하는 값을 넣어주는 방식으로 동작한다.
class MyClass(val num: Int) {
// secondary constructor
constructor(num1: Int, num2: Int) : this(num1 + num2)
}
속성
property는 val(수정 불가)이 될 수도, var(수정가능)이 될 수도 있다.
따로 private 키워드를 붙여주지 않으면 클래스 외부에서도 접근할 수 있는 public 속성이 된다.
class MyClass {
val A = "Immutable | Public" // 클래스 외부 print 가능 재할당 불가
var B = "Mutable | Public" // 클래스 외부 print 가능 재할당 가능
private val C = "Immutable | Private" // 클래스 외부작업 아예 불가
private var D = "Mutable | Private" // 클래스 외부작업 아예 불가
}
속성 타입으로 람다함수나 inner class를 넣으면 더 다양한 작업을 할 수 있다.
getter와 setter에서 타입은 inffered될 수 있지만 선언하려면 아래와 같이 수행한다.
class Rectangle(val width: Int, val height: Int) {
val area: Int // property type is optional since it can be inferred from the getter's return type
get() = this.width * this.height // custom accessors
// 한 줄로 쓸 수도 있다.
val height get() = this.height.toString()
var editMe : Int
get() = this.editMe.toString
set(value){...} // value라고 쓰는게 컨벤션이다.
}
Tip ) 속성을 밖에서 수정할 수 없게 만드는 방법 - private set
속성을 밖에서 변경할 수 없게 만들 때 val을 쓰면 된다고 생각할 수도 있지만 그러면 내부에서도 수정이 안되는 문제가 생긴다. 이 문제는 단순히 변수 선언부 아래에 탭을 들여넣고 setter를 private으로 설정하는 것으로 해결된다.
class Persen(){
var hobby : String = "singing"
private set
}
Instance 생성
인스턴스화는 실제로 메모리에 객체를 위한 자리를 할당하는 과정이다. 주로 아까 만들어둔 Constructor를 사용한다.
- val 변수명 = 클래스()
참고한 자료
Kotlin 공식 사이트 - class : https://kotlinlang.org/docs/classes.html
'프로그래밍 언어 > Kotlin' 카테고리의 다른 글
[JUnit] assert 함수 종류 (0) | 2022.10.05 |
---|---|
[IntelliJ] JUnit5 라이브러리 maven으로 적용하기 (0) | 2022.10.05 |
Kotlin의 class(4) - Enum class (1) | 2022.10.03 |
Kotlin의 class(3) - Nested and inner classes (0) | 2022.10.03 |
Kotlin의 class(2) - abstract class와 interface (0) | 2022.10.03 |