data class
๋ฐ์ดํฐ ํด๋์ค๋ ํ์ ๋ฉ์๋๋ฅผ ์ปดํ์ผ๋ฌ๊ฐ ๋ง๋ค์ด์ค๋ค. ์ฝํ๋ฆฐ ์ปดํ์ผ๋ฌ๋ ์ด๋ฏธ ํ๋กํผํฐ ์ ๊ทผ์, ์์ฑ์๊ฐ์๊ฑธ ์๋ฐ์๋ ๋ค๋ฅด๊ฒ ์์์ ๋ง๋ค์ด ์ฃผ๋๊ฑธ ์ด์ ๋ด์ฉ์์ ๋ณผ ์ ์์๋๋ฐ, ๊ฑฐ๊ธฐ์ ํ๋ฐ ๋ ๋๊ฐ์ toString(), equals(), hashCode()์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ปดํ์ผ๋ฌ๊ฐ ๋ง๋ค์ด์ค๋ค.
์ฝํ๋ฆฐ์ == ๋ equals()๋ก ๋ด๋ถ์ ์ผ๋ก ํธ์ถ๋์ด ๊ฐ์ฒด๋ฅผ ๋น๊ตํ๋ค. ๋ฐ๋ผ์ ์๋ฐ์์ ๋ฌธ์ ๊ฐ ๋๋ ์ฐธ์กฐ๋น๊ต๊ฐ ์ฝํ๋ฆฐ์ ==์์๋ ๋ฐ์ํ์ง์๋๋ค. ์ฐธ์กฐ ๋น๊ต๊ฐ ํ์ํ๋ค๋ฉด ===๋ก ์ฌ์ฉํ๋ฉด ๋๋ค.
val client1 = Client("Alice", 342562)
val client2 = Client("Alice", 342562)
println(client1 == client2) println(client1 === client2)
๋๋ค false์ด๋ค. ๊ฐ์ฒด๋ฅผ ๋น๊ตํ๊ธฐ ๋๋ฌธ์ธ๋ฐ, ๊ฐ์ด ๊ฐ์ ๊ฑธ ๋น๊ตํ๋ ค๋ฉด equals๋ฉ์๋๋ฅผ Clientํด๋์ค ๋ด๋ถ์์ ์ค๋ฒ๋ผ์ด๋ ํ์ฌ ๊ตฌํํด์ผ๋๋ค.
hashCode()๋ ์ ๋ชจ๋ฅด๋ ๊ฐ๋ ์ธ๋ฐ, equals()๊ฐ true๋ฅผ ๋ฐํํ๋ ๋ ๋น๊ต๊ฐ์ฒด๋ ๊ฐ์ hashCode๋ฅผ ๋ฐํํด์ผํ๋ค๋ ํน์ง์ด ์๋ค. ํด์ ์ปจํ ์ด๋๋ผ๊ณ ๋ ํ๋๋ฐ, ๊ตฌ๋ณID๋ผ๊ณ ๋ณผ ์๋ ์๋ค.
์๋๋ผ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์ญํ ๋ง ํ๋ ํด๋์ค์ ์ด๋ฐ ๋ฉ์๋๋ฅผ ์ํฉ์ ๋ง๊ฒ ์ค๋ฒ๋ผ์ด๋ ํด์ ์ฌ์ฉํด์ผ๋์ง๋ง, data class๋ก ์์ฑํ ํด๋์ค๋ ์ด ๋ฉ์๋๋ค์ ์๋ ์์ฑํ๋ค.
data class Client(val name: String, val postalCode: Int)
๋ฐ์ดํฐ ํด๋์ค์ ์ฃผ์์ฑ์๋ก ์ ์ธ๋ ํ๋กํผํฐ๋ฅผ ๊ณ ๋ คํด equals, hashCode๊ฐ ๋ง๋ค์ด์ง๋ค.
๋ถ๋ณ์ฑ
๋ฐ์ดํฐ ํด๋์ค์ ํ๋กํผํฐ๋ var๋ก๋ ์ ์ธํ ์ ์์ง๋ง, val๋ก ๊ถ์ฅ๋๋ค. ๋ถ๋ณ์ฑ์ด ํ์์ ์ธ ํ์ ์ปจํ ์ด๋์ ๋ฐ์ดํฐ ํด๋์ค๋ฅผ ๋ด๋ ๊ฒฝ์ฐ, var๋ก ์ ์ธํ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ์ปจํ ์ด๋ ์ํ๊ฐ ๋ณํ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ค์ค๋ ๋์ผ ๋ ๋ ์์ ํ๋ค. ์ฐ๊ธฐ๋ก ์ ๊ทผํ ์๊ฐ ์์ผ๋ ๋๊ธฐํํ ํ์๊ฐ ์ค์ด๋ค๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ผ var๋ก ์ ์ธํด์ผํ๋ง ํ๋ ๊ฒฝ์ฐ์๋ ์ด๋ค ๋ฐฉ์์ผ๋ก ํด๊ฒฐํด์ผ๋ ๊น?
copy()๊ฐ ์๋ค. val ํ๋กํผํฐ๋ฅผ copyํ์ฌ ๋ณต์ฌ๋ณธ์ ๊ฐ์ ์ฌ์ ์ ํ๋ค. ์ด๋ฌ๋ฉด ์๋ณธ์ ์ด์์๊ณ , ๋ณต์ฌ๋ณธ์ ์ ๊ฑฐํด๋ ์๋ณธ์ ์ํฅ์ด ์๋ค.
val bob = Client("Bob", 973293)
println(bob.copy(postalCode = 382555))
// Client๋ data class ๊ฐ์ฒด.
์์ delegation
๋ฐ์ฝ๋ ์ดํฐ ํจํด์ด ์์๋ก ๋์์๋ค. ํค๋ํผ์คํธ GoF ๋์์ธํจํด ์ฑ ์ ์ฝ์ผ๋ฉด์ ๋์๋ ๊ฑด๋ฐ, ํ์ํ ๊ธฐ๋ฅ์ด ์์ผ๋ฉด ์์๋ฐ์ ๊ฒ ์์ ๋ง์์์ ์๋ก ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ๋ฐฉ์์ด๋ค. ์ฝํ๋ฆฐ์์๋ ์ด๊ฑธ by ํค์๋๋ก ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ค.
class CountingSet<T>(
val innerSet: MutableCollection<T> = HashSet<T>()
) : MutableCollection<T> by innerSet {
var objectsAdded = 0
override fun add(element: T): Boolean {
objectsAdded++
return innerSet.add(element)
}
override fun addAll(c: Collection<T>): Boolean {
objectsAdded += c.size
return innerSet.addAll(c)
}
}
innerSet์ ์์๋ฐ์์ ํ์ํ add, addAll ๋ฉ์๋๋ง ์ฌ์ ์ํ์ฌ ์ฌ์ฉํ๋ ๋ชจ์ต์ด๋ค.
object
object๋ ํด๋์ค ์ ์์ ๋์์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ํค์๋๋ค. ํค์๋ํ๋๋ก ์ฑ๊ธํด์ ๋ง๋ค์ ์๊ฒ๋๋ค.
object CaseInsensitiveFileComparator : Comparator<File> {
override fun compare(file1: File, file2: File): Int {
return file1.path.compareTo(file2.path,
ignoreCase = true)
}
}
์์ฑ์๋ฅผ ๊ฐ์ฒด์ ์ธ์ ์ธ์์๋ค. ์ ํํ๋ ์ ์ธ๊ณผ ๋์์ ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ์ธ ํ์๊ฐ ์๋ค. ๋ถ์์ฑ์๋ ๋ง์ฐฌ๊ฐ์ง๋ค. ์์กด๊ด๊ณ๊ฐ ๋ง์์ง๋ ๋๊ท๋ชจ ์ปดํฌ๋ํธ์์๋ ์ด๋ฐ ํน์ง์ด ์์ฑ์ ์ ์ดํ ์ ์๊ณ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ ํ ์ ์์ด ๋จ์ ์ด ๋๋๋ฐ, ์ด๋๋ ์์กด๊ด๊ณ ์ฃผ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํด์ ์ฌ์ฉํด์ผํ๋ค.
object๋ ํด๋์ค ์์์ ์ ์ธํ ์๋ ์๊ณ , ์ด๋ ์ญ์ ์ด ๊ฐ์ฒด์ ์ธ์คํด์ค๋ ํ๋๋ฟ์ด๋ค.
data class Person(val name: String) {
object NameComparator : Comparator<Person> {
override fun compare(p1: Person, p2: Person): Int =
p1.name.compareTo(p2.name)
}
}
์ฝํ๋ฆฐ ํด๋์ค ์์๋ static ํ ๋ฉค๋ฒ๋ฅผ ๊ฐ์ง ์ ์๋ค. ๋ฐ๋ผ์ ํด๋์ค ๋ฐ์ ์ต์์ ํจ์/ ํ๋กํผํฐ๋ก ์ ์ธํด์ ์ฌ์ฉํ๋๋ฐ, ์ต์์ ๋ฉค๋ฒ๋ private๋ก ๋ ๋ฉค๋ฒ์ ์ ๊ทผํ ์ ์๋ค๋ ๋จ์ ์ด์๋ค. ์ด๋ ์ฌ์ฉ๋๋ ๊ฒ์ด ๋๋ฐ๊ฐ์ฒด companion object์ด๋ค.
class A {
companion object customName {
fun bar() {
println("Companion object called")
}
}
}
์ด๋ ๊ฒ ์ ์ธ๋ ๋๋ฐ ๊ฐ์ฒด์ ๋ฉค๋ฒ์ ์ ๊ทผํ๋ ค๋ฉด A.bar() ์ฒ๋ผ ํ๋ฉด ๋๋ค. private ๋ฉค๋ฒ์ ์ ๊ทผํ ์์๋ค๊ณ ํ๋๋ฐ, ์ด ๋ง์ ๊ณง private ์์ฑ์๋ฅผ ์ฌ๊ธฐ์ ํธ์ถํ๋ฉด ๋๋ค๋ ๋ป์ด๋ค. ๋๋ฐ๊ฐ์ฒด๋ ํด๋์ค ์/๋ฐ์ private ๋ฉค๋ฒ์ ์ ๊ทผ ๊ฐ๋ฅํด์, private ์ฒ๋ฆฌ๋ ์ฃผ ์์ฑ์๋ฅผ ์ฌ๊ธฐ์ ํธ์ถํ๋ ์ผ์ข ์ ํฉํ ๋ฆฌ ํจํดํํ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ฝ๋๋ก ๋ฐ๋ก ๋ณด๋ฉด ์ดํด๊ฐ ๋น ๋ฅด๋ค.
class User private constructor(val nickname: String) {
companion object {
fun newSubscribingUser(email: String) =
User(email.substringBefore('@'))
fun newFacebookUser(accountId: Int) =
User(getFacebookName(accountId))
}
}
๋๋ฐ๊ฐ์ฒด์ ๋ฉ์๋๋ private ์์ฑ์๋ฅผ ์ ์ดํ ์ ์๋ ํฉํ ๋ฆฌ ๋ฉ์๋๋ค.
User ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผํ๋ ๊ฒฝ์ฐ, ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๋ํ object์ด๊ธฐ ๋๋ฌธ์ ํฉํ ๋ฆฌ ๋ฉ์๋๋ก ์์ฑ๋ ์ธ์คํด์ค๋ ์ฃผ์๋ณ๋ก ์ ์ผํ๊ณ , ์ด๋ฏธ ์์ฑ๋ ์ธ์คํด์ค์ ์ ๊ทผ ํ ๋๋ ์บ์์ ์๋ ์ธ์คํด์ค๋ฅผ ๋ฐํํ ์ ์๋ค.
๋๋ฐ ๊ฐ์ฒด๋ ํด๋์ค ์์ ์ ์๋ ์ผ๋ฐ ๊ฐ์ฒด์ด๊ณ ์ธํฐํ์ด์ค ์์, ํ์ฅํจ์, ํ๋กํผํฐ ์ ์ ,๋ค ๊ฐ๋ฅํ๋ค. ๋๋ฐ ๊ฐ์ฒด์์ ๊ตฌํ๋ ์ธํฐํ์ด์ค๋ ๋๋ฐ๊ฐ์ฒด๋ฅผ ๋๋ฌ์ผ ํด๋์ค ์ด๋ฆ์ผ๋ก ์ ๊ทผ ํ ์์๋ค.
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋๋ฐ๊ฐ์ฒด๋ฅผ ๊ฐ๋ ํด๋์ค์ ์ด๋ฆ์ ์ฌ์ฉํด ํ์ํ ๋ฉ์๋๋ก ์ธ์คํด์ค๋ฅผ ๋๊ธธ ์ ์๋ค.
fun loadJson<T>(factory: C<T>): T{
}
class P(val name: String){
companion object : C<P>{
// ์ธํฐํ์ด์ค ๊ตฌํ
override fun fromJson(jsonText: String):P = ...
}
}
loadJson(P)
์ด๋ฐ์์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
์ด๋ฆ์์ด ์ ์๋ ๋๋ฐ๊ฐ์ฒด์ ์ ๊ทผํ๊ธฐ ์ํด์๋ Companion์ด๋ผ๋ ์ด๋ฆ์ ์จ์ผ๋๋๋ฐ, ๋๋ฐ๊ฐ์ฒด ํ์ฅ ์์์ ๊ฐ์ด ๋ณด์.
class A {
companion object {
fun bar() {
println("Companion object called")
}
}
}
fun A.Companion.foo(): String{
return "foo"
}
fun main(args: Array<String>) {
A.bar()
A.foo()
}
๋๋ฐ๊ฐ์ฒด์ ํ์ฅํจ์๋ฅผ ์ ์ํ๋ ค๋ฉด ๋น ๋๋ฐ ๊ฐ์ฒด๋ผ๋ ๊ฐ๊ณ ์์ด์ผํ๋ค.
๋ฌด๋ช ๊ฐ์ฒด๋ฅผ ์ ์ํ ๋๋ object๊ฐ ์ฌ์ฉ๋๋ค. ์๋๋ก์ด๋์ setOnClickListener์์๋ ๋ณด์๋ ๋ฐฉ๋ฒ์ธ๋ฐ
etSignupPhone.setOnClickListener { object : View.OnClickListener {
override fun onClick(v: View?) {
TODO("Not yet implemented")
}
} }
์ด๋ฐ์์ผ๋ก ์์ ์๋ ์ฌ์ฉํ์๋ค. EditText์์ TextWatcher๋ฅผ object๋ก ๋๊ธฐ๋ ๊ฒ๋ ์ด ๊ฒฝ์ฐ๋ค. ๊ฐ์ฒด ์ด๋ฆ์ด ์๋๋ฐ, ๊ฐ์ฒด ์์ ํน์ง์ด๋ค. ์ด๋ฆ์ ๋ถ์ฌ์ผ ํ๋ค๋ฉด
val clickListener = object : View.OnClickListener {
override fun onClick(v: View?) {
TODO("Not yet implemented")
}
}
์ด๋ฐ์์ผ๋ก ๋ณ์์ ๋์ ํ์ฌ ์ฌ์ฉํ๋ฉด ๋๋ค.
์ค์ํ ์ ์ ๋ฌด๋ช ๊ฐ์ฒด๋ ์ฑ๊ธํด์ด ์๋๋ผ, ์ฌ์ฉ ์ ๋ง๋ค ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ค๋ ๊ฒ์ด๋ค. ๊ฐ์ฒด ์์ ๋ฌด๋ช ๊ฐ์ฒด ์์์ ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํด์ผํ๋ ๊ฒฝ์ฐ์ ์ ์ฉํ๋ค. ์ด ์์๊ฐ ๋ฐ๋ก EditText์ addTextChangedListener์ธ ๊ฒ์ด๊ณ , ๊ตฌํ์ด ํ์ํ ์ถ์๋ฉ์๋๊ฐ ํ๋์ธ ์ธํฐํ์ด์ค๋ฅผ ๋ปํ๋ SAM ์ข ๋ฅ์ธ setOnClickListener๋ ๋๋ค๋ฅผ ์ฌ์ฉํด ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ค.
"๋๊ธ, ๊ณต๊ฐ ๋ฒํผ ํ ๋ฒ์ฉ ๋๋ฅด๊ณ ๊ฐ์ฃผ์๋ฉด ํฐ ํ์ด ๋ฉ๋๋ค"
'๐ > ์ฝํ๋ฆฐ ์ธ ์ก์ ๐' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Kotlin in action(6) (0) | 2023.10.10 |
---|---|
Kotlin in action(5) (0) | 2023.10.10 |
Kotlin in action(3) (0) | 2023.10.10 |
Kotlin in action(2) (0) | 2023.10.10 |
Kotlin in action(9) (0) | 2023.10.10 |