POJO (Plain Old Java Object)
class Person {
String name;
int age;
int height;
double weight;
public Person(String name, int age, int height, double weight) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
위와 같이 데이터를 담을 목적으로 만든 클래스를 POJO (Plain Old Java Object)라고 합니다.
별 다른 기능을 하지 않는, 정말 데이터를 담기 위한 클래스인데요.
인텔리제이 등 요즘은 IDE가 발전하여 getter/setter와 생성자를 자동으로 생성해주지만,
아무래도 코드도 길어지고, 귀찮습니다. 결국 보일러 플레이트가 있다는 건 똑같고요.
코틀린의 자동 getter / setter
// 몸통(중괄호 { }) 가 필요하지 않을 경우 생략 가능
class Person(val name:String, var age:Int, var height:Int, var weight:Double)
fun main() {
val person = Person("홍길동", 30, 180, 80.5)
println(person.name) // person.getName() -> person.name 으로 접근 가능
person.age = 30 // person.setAge(30) -> person.age = 30 으로 접근 가능
println(person.age) // person.getAge() -> person.age로 접근 가능
}
// 출력
>>> 홍길동
30
하지만, 코틀린에서는 getter / setter를 자동으로 만들어줍니다.
그 길던 코드가 단 한 줄로, 생성자, getter / setter 까지 다 처리했습니다.
프로퍼티 (Property) vs 변수 (Variable)
class Person {
val name:String = "홍길동"
var age:Int = 20
var height:Int = 180
var weight:Double = 80
}
클래스 안에서 정의된 변수는 프로퍼티라고 부릅니다.
이는 변수이긴 하지만, getter / setter가 내장되어 있기 때문이죠.
class Person {
val name: String = "홍길동"
get() = field
set(value) {field = value}
}
코틀린에서는 위와 같이, getter와 setter가 자동으로 내장되어 있습니다.
개발자가 커스텀 getter / setter를 필요로 하는게 아니라면,
getter / setter를 굳이 만들어 줄 필요가 없어요.
getter / setter 커스텀
class Person {
var name: String = "홍길동"
set(value) {
field = "$value (개명함)"
}
get() {
field = "나는 $field 이다"
return field
}
}
fun main() {
val person = Person()
println(person.name)
person.name = "김철수"
println(person.name)
}
// 출력
>> 나는 홍길동 이다
나는 김철수 (개명함) 이다
물론, 이 처럼 getter / setter를 커스터마이징 하여 사용하는 것이 가능합니다.
데이터를 담기 위한 클래스 Data Class
data class Person(val name: String, var age:Int, var height:Int, var weight:Double)
코틀린에서는 이러한 데이터를 다루는데 최적화 된 데이터용 클래스인 data class를 제공합니다.
data class는 아래 기능들을 기본적으로 제공합니다.
copy()
data class Person(val name:String, var age:Int, var height:Int, var weight:Double)
fun main() {
val person = Person("홍길동", 10, 160, 50.6)
val person2 = person.copy()
val person3 = person.copy(name="전우치")
}
객체를 복사하거나, 특정 프로퍼티만 바꿔 복사할 때, copy() 메소드를 사용할 수 있습니다.
toString()
data class Person(val name:String, var age:Int, var height:Int, var weight:Double)
fun main() {
val person = Person("홍길동", 10, 160, 50.6)
println(person.toString())
}
// 출력
>>> Person(name=홍길동, age=10, height=160, weight=50.6)
객체의 원소를 출력하는 toString() 역시 자동으로 지원합니다.
진짜 편해요.
data class Person(val name:String, var age:Int, var height:Int, var weight:Double) {
override fun toString(): String {
return "이름 : $name, 나이 : $age, 키 : $height, 몸무게 : $weight"
}
}
fun main() {
val person = Person("홍길동", 10, 160, 50.6)
println(person.toString())
}
// 출력
>>> 이름 : 홍길동, 나이 : 10, 키 : 160, 몸무게 : 50.6
물론, toString()을 오버라이딩하여 커스텀하여 사용할 수 있습니다.
구조 분해 (Destructuring)
data class Person(val name:String, var age:Int, var height:Int, var weight:Double)
fun main() {
val person = Person("홍길동", 10, 160, 50.6)
val (name, age, height, weight) = person
}
코틀린에서는 디스트럭쳐링일 지원합니다.
객체의 구조를 분해하여, 각각의 변수에 할당하는 기능입니다.
이 역시 익숙해지면 굉장히 편한 기능 중 하나입니다.
다만, data class의 프로퍼티가 많으면, 오히려 더 귀찮을 수 있으니
때에 따라 적절히 사용해야겠지요.
데이터 클래스 비교
class Person(var name: String, var age:Int, var height:Int, var weight:Double)
fun main() {
val p1 = Person("John", 20, 180, 70.5)
val p2 = Person("John", 20, 180, 70.5)
println(p1 == p2)
}
// 출력
>> false
==============================================================
data class Person(var name: String, var age:Int, var height:Int, var weight:Double)
fun main() {
val p1 = Person("John", 20, 180, 70.5)
val p2 = Person("John", 20, 180, 70.5)
println(p1 == p2)
}
// 출력
>> true
객체는 모두 서로 다릅니다. 따라서 두 객체를 비교하면 당연히 false가 나옵니다.
하지만 data class는 ==를 사용해 비교 시, 객체의 프로퍼티를 비교하기 때문에,
객체의 프로퍼티가 같을 경우 true를 반환합니다.
'코틀린 파헤치기 > 2부. 코틀린 객체지향' 카테고리의 다른 글
[코파기 2부] 6. 코틀린과 늦은 초기화 : lazy, lateinit (0) | 2023.03.15 |
---|---|
[코파기 2부] 5. 코틀린과 추상 클래스와 인터페이스 (+ 둘의 차이점) (3) | 2023.03.15 |
[코파기 2부] 4. 코틀린과 접근 제한자 (0) | 2023.03.15 |
[코파기 2부] 3. 코틀린과 상속(Inheritance)와 오버라이딩(Override) (0) | 2023.03.15 |
[코파기 2부] 1. 코틀린과 클래스, 객체, 생성자 (0) | 2023.03.15 |