굥뷰를 햡시댜
[Kotlin] Properties and Fields 본문
1. Property 선언
- 코틀린 클래스는 Property를 가질 수 있음( var(mutable) / val(read-only) )
class Address {
var name: String = "Kotlin"
val city: String = "Seoul"
}
- Property 사용은 자바의 필드를 사용하듯이 하면 됨
fun copyAddress(address: Address): Address {
val result = Address()
result.name = address.name
//...
return result
}
2. Property 문법
//전체 문법
var <propertyName>[: <ProopertyType>] [=<property_initializer]
[<getter>]
[<setter>]
/*
-> 생략 가능한 옵션들
-> PropertyType - property_initializer로 타입을 추론 가능할 경우 생략 가능!
-> property_initializer
-> getter - 코틀린에서는 선언과 동시에 자동으로 getter가 만들어진다(var, val)
-> setter - 코틀린에서는 선언과 동시에 자동으로 setter가 만들어진다(var, val은 불가능)
-> val은 선언과 동시에 초기화 해줘야하고 1번만 할당 가능하기 때문에 setter가 지원되지 않음
*/
- ex)
fun main(args: Array<String>) {
var obj = Address()
println(obj.name)
}
class Address {
var name: String = "Kotlin"
get() {
return field + "!!!"
}
set(value) {
field = value
}
}
//-> 출력 결과
//Kotlin!!!
3. var (mutable) Property
- ex)
class Address {
//default getter와 setter
//타입은 Int
var initialized = 1
//error: 오류 발생
//default getter와 setter를 사용한 경우
//명시적인 초기화가 필요함
var allByDefault: Int?
}
4. val (read-only) Property
- var대신 val 키워드 사용
- setter가 없음
class Address {
//default getter
//타입은 Int
val initialized = 1
//error: 오류 발생
//default getter
//명시적인 초기화가 필요
val allByDefault: Int?
}
5. Custom accessors ( getter, setter )
- custom accessor는 Property 선언 내부에 일반 함수처럼 선언할 수 있음
- getter
val isEmpty: Boolean
get() = this.size == 0
- setter
//관습적으로 setter의 Parameter의 이름은 value임(변경은 가능함)
var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value)
}
6. Property
- accessor에 가시성 변경이 필요하거나 어노테이션이 필요한 경우 기본 accessor의 수정 없이 body 없는 accessor를 통해 정의 가능
var setterVisibility: String = "abc"
private set
var setterWithAnnotation: Any? = null
@Inject set
- Body를 작성해도 무방함
var setterVisibility: String = "abc"
private set(value) {
field = value
}
7. Backing Fields
- 코틀린 클래스는 field를 가질 수 없음
- field라는 식별자를 통해 접근할 수 있는, automatic backing field를 제공함
- field는 Property의 accessor에서만 사용가능함
//the initializer value is written directly
//to the backing field
var counter = 0
set(value) {
if(value>=0) field = value
}
8. Backing Fields 생성 조건
- accessor중 1개라도 기본 구현을 사용하는 경우
- custom accessor에서 field 식별자를 참조하는 경우
//the initializer value is written directly to the backing field
var counter = 0
set(value) {
if(value >= 0) field = value
}
- 아래의 경우 backing field를 생성하지 않음
val isEmpty: Boolean
get() = this.size == 0 //get에서 field를 사용하지 않기 때문
9. Backing Properties
- "implicit backing field" 방식이 맞지 않는 경우에는 "backing property"를 이용할 수도 있음
- ex) 명시적으로 객체를 생성하는 프로그래밍을 하고 싶을때 사용!!!
private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
get() {
if(_table == null) {
_table = HashMap()
}
return _table ?: throw AssertionError("null ")
}
10. Compile-Time Constants
- const modifier를 이용하면 컴파일 타임 상수를 만들 수 있음
- 조건 -> Top-level 이거나 object의 멤버이거나 String으로 초기화된 경우
const val SUBSYSTEM_DEPRECATED.String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED)
fun foo() {...}
11. Late-initialized Properties
- 나중에 초기화되는 Property
- 일반적으로 Property는 non-null 타입으로 선언되는데 간혹 non-null타입 property를 사용하고 싶지만, 생성자에서 초기화를 해줄 수 없는 경우가 있음( Dependency injection, Butter knife, Unit test의 setup 메소드)
public class MyTest {
lateinit var subject: TestSubject //lateinit을 써서 나중에 초기화할 것이라고 알림
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() //dereference directly
}
}
- 객체가 constructor에서는 할당되지 못하지만 여전히 non-null 타입으로 사용하고 싶은 경우 Lateinit modifier를 사용 가능
- 조건
|
'언어 > Kotlin' 카테고리의 다른 글
[Kotlin] Inheritance (0) | 2019.04.24 |
---|---|
[Kotlin] Class (0) | 2019.04.24 |
[Kotlin] Packages, Return and Jumps (0) | 2019.04.24 |
[Kotlin] Control Flow (0) | 2019.04.24 |
[Kotlin] Basic Types (0) | 2019.04.23 |
Comments