๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“ฑ/๐Ÿ“—Kotlin

[Kotlin] ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๐Ÿ’ก์ƒ์„ฑ์ž, ์ƒ์†, ์ถ”์ƒ, interface๐Ÿ’ก

 


โ–ช๏ธ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

· ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋‚˜ ๊ธฐ๋Šฅ์„ ๊ฐ์ฒด๋กœ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ด๋‹ค.

· ๋งค๊ฐœ์ฒด ํ•˜๋‚˜์˜ ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ์ฒด ํ•˜๋‚˜๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ ๊ด€๋ฆฌํ•˜๊ณ ์ž ํ•˜๋Š” ๋งค๊ฐœ์ฒด์˜ ์ˆ˜๋งŒํผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

fun main() {
    // ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ
    val obj1 = TestObject()
    val obj2 = TestObject()
    
    // obj1์—๋Š” ์ด๋ฏธ ๋งŒ๋“ค์–ด๋…ผ ๊ฐ์ฒด๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ obj3์—๋Š” obj1์˜ ์ฃผ์†Œ๊ฐ’์ด ๋“ค์–ด๊ฐ(๊ฐ™์€ ๊ฐ์ฒด)
    val obj3 = obj1
    
    // ๊ฐ์ฒด์˜ ์ฃผ์†Œ๊ฐ’์ด ๋‚˜์˜ด
    println("obj1 : $obj1")
    println("obj2 : $obj2")
    println("obj3 : $obj3")
}

class TestObject

 

๋ฉค๋ฒ„ ๋ณ€์ˆ˜

fun main() {
    val obj = TestObject()
    
    println("num1, num2 : ${obj.num1}, ${obj.num2}")
    
    // num1์€ val๋กœ ์„ ์–ธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†์Œ
//  obj.num1 = 20
    obj.num2 = 200

    println("num1, num2 : ${obj.num1}, ${obj.num2}")
}

class TestObject {
    // ๋ฉค๋ฒ„ ๋ณ€์ˆ˜
    val num1 = 10
    var num2 = 100
}

 

๋ฉค๋ฒ„ ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜)

fun main() {
    val obj = TestObject()

    obj.testMethod()
}

class TestObject {
    // ๋ฉค๋ฒ„ ๋ฉ”์„œ๋“œ
    fun testMethod() {
        println("testMethod ํ˜ธ์ถœ")
    }
}

 

 

โ–ช๏ธ์ƒ์„ฑ์ž

 

init

· ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰๋  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ณณ์ด๋‹ค.

· init ์ฝ”๋“œ ๋ธ”๋ก์„ ๋งŒ๋“ค์–ด ์ฃผ๋ฉด ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

fun main() {
    val obj = TestClass()
}

class TestClass {
    init {
        println("init ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค")
    }
}

 

constructor

· constructor๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒ์„ฑ์ž๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

· ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฐœ์ˆ˜๋‚˜ ์ž๋ฃŒํ˜•์„ ๋‹ฌ๋ฆฌํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

fun main() {
    val obj1 = TestClass()
    val obj2 = TestClass(10)
    val obj3 = TestClass(10, 20)
}

class TestClass {
    constructor() {
        println("๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ์ƒ์„ฑ์ž")
    }

    constructor(num1 : Int) {
        println("๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ํ•œ ๊ฐœ์ธ ์ƒ์„ฑ์ž")
    }

    constructor(num1 : Int, num2 : Int) {
        println("๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ธ ์ƒ์„ฑ์ž")
    }
}

 

์ฃผ ์ƒ์„ฑ์ž

· ํด๋ž˜์Šค๋ช… ์˜†์— ๋ฐ”๋กœ ์ฃผ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.

class TestClass1 constructor(var num1 : Int, var num2 : Int)
// constructor ์ƒ๋žต ๊ฐ€๋Šฅ
class TestClass2 (var num1 : Int, var num2 : Int)

 

๋ณด์กฐ ์ƒ์„ฑ์ž

fun main() {
    // ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜๋งŒ ๋„ฃ์—ˆ์œผ๋ฏ€๋กœ ๋ณด์กฐ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ
    val obj = TestClass(10)
}

class TestClass constructor(var num1 : Int, var num2 : Int) {
    // ๋ณด์กฐ ์ƒ์„ฑ์ž
    constructor(num : Int) : this(num, 30) {
        println("๋ณด์กฐ ์ƒ์„ฑ์ž ํ˜ธ์ถœ")
   }
}

 

 

โ–ช๏ธ์ƒ์†

· ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ๋‹ค๋ฅธ ํด๋ž˜์Šค๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ถ€๋ถ„์„ ๋ฌผ๋ ค๋ฐ›์€ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

· SuperClass : ์ƒ์†์„ ํ•ด์ฃผ๋Š” ํด๋ž˜์Šค(๋ถ€๋ชจ)

· SubClass : ์ƒ์†์„ ๋ฐ›๋Š” ํด๋ž˜์Šค(์ž์‹)

· ๋ถ€๋ชจ ํด๋ž˜์Šค๋Š” open ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋ฐ” ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝ๋  ๋•Œ final ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™๋Š”๋‹ค.

fun main() {
    val sub = SubClass()

    println("${sub.subMember}")
    sub.subMethod()

    // ์ƒ์†์„ ๋ฐ›์•˜๊ธฐ๋•Œ๋ฌธ์— ๋ถ€๋ชจ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜, ๋ฉ”์„œ๋“œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ์Œ
    println("${sub.superMember}")
    sub.superMethod()
}

// ์ƒ์†์„ ํ•ด์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— oepn์„ ๋ถ™์—ฌ์ฃผ์ž
open class SuperClass {
    var superMember = 100

    fun superMethod() {
        println("superMethod ํ˜ธ์ถœ")
    }
}

// ์ƒ์†์„ ๋ฐ›์„ ๊ฒฝ์šฐ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•จ
// ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์—†์œผ๋ฏ€๋กœ ()๋งŒ ํ•ด์คŒ
class SubClass : SuperClass() {
    var subMember = 100

    fun subMethod() {
        println("subMethod ํ˜ธ์ถœ")
    }
}

 

· ์ƒ์†์„ ๋ฐ›์„ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์ฃผ ์ƒ์„ฑ์ž๋ฅผ ๋ถˆ๋Ÿฌ์ค˜์•ผ ํ•œ๋‹ค.

// ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ํ•œ๊ฐœ์ธ ๋ถ€๋ชจ
// ์—ฌ๊ธฐ์„œ ์ฃผ ์ƒ์„ฑ์ž๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜ ํ•œ๊ฐœ์งœ๋ฆฌ
open class SuperClass(var num : Int)

// ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ์ค‘ ํŽธํ•œ๋Œ€๋กœ ์“ฐ๋ฉด ๋จ
class SubClass1 : SuperClass(100)
class SubClass2 : SuperClass {
    constructor() : super(100)
}

 

 

โ–ช๏ธ์ง€์—ฐ ์ดˆ๊ธฐํ™”

 

lateinit

· var๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜์˜ ์ดˆ๊ธฐํ™”๋ฅผ ๋’ค๋กœ ๋ฏธ๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

· ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•œ๋‹ค.

· val๋กœ๋Š” ์„ ์–ธํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ๋ฐ˜๋“œ์‹œ var๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.

fun main() {
    val obj = LatClass()
    obj.letMethod()
}

class LatClass {
    lateinit var str : String

    fun letMethod() {
        // ::๋Š” ๋ฆฌํ”Œ๋ ‰์…˜์ด๋ผ ๋ถ€๋ฅด๊ณ  ํ•ด๋‹น ๊ฐ์ฒด์™€ ๊ด€๋ จ๋œ ํด๋ž˜์Šค๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
        // isInitialized๋Š” ์ดˆ๊ธฐํ™” ๋œ์ ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•จ
        if(!::str.isInitialized) {
            str = "๋ฌธ์ž์—ด"
            println("$str")
        }
    }
}

 

by lazy

· val๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” by lazy ์ฝ”๋“œ ๋ธ”๋ก์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

· ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

fun main() {
    val obj = BylClass()

    println("str : ${obj.str}")
}

class BylClass {
    val str by lazy {
        println("str ์‚ฌ์šฉ")
        "๋ฌธ์ž์—ด"
    }
}

 

 

โ–ช๏ธabstract

· ์ถ”์ƒ ํด๋ž˜์Šค์ถ”์ƒ ๋ฉ”์„œ๋“œ : ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ

· ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด์„œ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋‹ค.

· ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

· ์ถ”์ƒ ํด๋ž˜์Šค์˜ ๋ชฉ์ ์€ ์ž์‹ ํด๋ž˜์Šค์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ Overriding ํ•˜๊ฒŒ ํ•˜๋ ค๋Š” ๊ฒƒ์ด๋‹ค. (๊ฐ•์ œ์„ฑ ๋ถ€์—ฌ)

· ํด๋ž˜์Šค๋ช… ์•ž์— open abstract๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด ๋œ๋‹ค.

fun main() {
    // ์ถ”์ƒ ํด๋ž˜์Šค๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Œ
    //val obj = AbsClass1()
    
    val obj = AbsClass2()
    obj.absMethod()
}

open abstract class AbsClass1 {
    open abstract fun absMethod()
}

class AbsClass2 : AbsClass1() {
    override fun absMethod() {
        println("absMethod ํ˜ธ์ถœ")
    }
}

 

 

โ–ช๏ธinterface

· ๊ฐ์ฒด์˜ ์ฃผ์†Œ ๊ฐ’์„ ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ๋ณ€์ˆ˜์— ๋‹ด์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.

· ํด๋ž˜์Šค๋Š” ํ•œ ๊ฐœ ์ด์ƒ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

fun main() {
    val obj = IntClass()
    obj.inter1Method()
    obj.inter2Method()
}

interface Inter1 {
    fun inter1Method() {
        println("inter1Method1 ํ˜ธ์ถœ")
    }
}

interface Inter2 {
    fun inter2Method() {
        println("inter2Method ํ˜ธ์ถœ")
    }
}

class IntClass() : Inter1, Inter2 {
    override fun inter1Method() {
        super.inter1Method()
        println("IntClass์—์„œ inter1Method ํ˜ธ์ถœ")
    }

    override fun inter2Method() {
        super.inter2Method()
        println("IntClass์—์„œ inter2Method ํ˜ธ์ถœ")
    }
}