코틀린은 간단한 값의 저장용도로 데이터 클래스를 제공한다.
data class 클래스명 (val 파라미터1: 타입, var 파라미터2: 타입)
데이터 클래스를 정의할 때 class 앞에 data 키워드를 사용해야 하고, 생성자 파라미터 앞에 입력하는 var(또는 val) 키워드는 생략할 수 없다.
// 정의 - 주로 코드 블록(클래스 스코프)을 사용하지 않고 간단하게 작성합니다.
data class UserData(val name: String, var age: Int)
// 생성 - 일반 class의 생성자 함수를 호출하는 것과 동일합니다.
var userData = UserData("Michael",21)
// name은 val로 선언되었기 때문에 변경 불가능합니다.
userData.name = "Sindy" (X)
// age는 var로 선언되었기 때문에 변경 가능합니다.
userData.age = 18 (O)
일반 클래스에서 toString() 메서드를 호출하면 인스턴스의 주소 값을 반환하지만, 데이터 클래스는 값을 반환하기 때문에 실제 값을 모니터링할 때 좋다.
Log.d("DataClass", "DataUser는 ${dataUser.toString()}")
copy() 메서드로 간단하게 값을 복사할 수 있다.
var newData = dataUser.copy()
일반 클래스처럼 init으로 생성자도 호출하고(생략가능), 메서드도 사용할 수 있다.
data class UserData(var name: String, var age: Int) {
init{
Log.d("UserData","initialized")
}
fun process() {
// 클래스와 동일하게 메서드 사용 가능
}
} // 클래스가 생성되면 Log.d 함수의 밸류값인 "initialized"가 출력된다.
코틀린은 클래스의 재사용을 위해 상속을 지원한다.
상속은 왜 필요할까?
개발을 하다보면 똑같은 코드를 반복적으로 사용해야 할 일이 매우 자주 있다.
그때마다 중복적으로 코딩해주지 않고 클래스를 상속받아 약간의 코드만 추가하면 앱에 필요한 기능을 추가할 수 있으므로 효율성이 높아지기 때문에 상속이 필요하다.
상속 대상이 되는 부모 클래스는 open 키워드로 만들어야만 자식 클래스에서 사용할 수 있다.
만약 open 키워드로 열려 있지 않으면 상속할 수 없다.
상속은 부모의 인스턴스를 자식이 갖는 과정이기 때문에 부모 클래스명 다음에 괄호를 입력해서 꼭 부모의 생성자를 호출해야 한다.
open class 상속될 부모 클래스 {
//코드
}
class 자식 클래스: 부모 클래스() <- 꼭 괄호 입력(부모 클래스 생성자 호출) {
// 코드
}
상속될 부모 클래스의 생성자에 파라미터가 있다면 자식 클래스의 생성자를 통해 값을 전달할 수 있다.
open class 부모 클래스(value: String) {
// 코드
}
class 자식 클래스(value: String) : 부모 클래스(value) {
// 코드
}
부모 클래스에 세컨더리 생성자가 있다면, 역시 자식 클래스의 세컨더리 생성자에서 super 키워드로 부모 클래스에 전달할 수 있다.
다음은 View 클래스를 상속받는 예제다.
class CustomView: View <- 부모 클래스명 다음 괄호 생략 {
constructor(ctx: Context): super(ctx)
constructor(ctx: Context, attrs: AttributeSet): super (ctx, attrs)
}
부모 클래스의 세컨더리 생성자를 이용하는 경우에는 부모 클래스명 다음에 오는 괄호를 생략한다.
open class parent {
var hello: String = "안녕하세요"
fun sayHello() {
Log.d("inheritance", "${hello}")
}
}
class Child: Parent() {
fun myHello() {
hello = "Hello!"
sayHello()
}
}
이 코드에서 Child에는 hello라는 프로퍼티와 sayHello라는 메서드가 없지만 myHello() 메서드 코드를 실행하면 로그에 "Hello!"가 출력된다.