Kotlin의 클래스 및 상속 - 3

2022. 4. 18. 11:27IT/안드로이드

반응형

이번에는 2에 이어서, getRoom() 함수를 사용하여 새 거주자가 방을 갖도록 하는 기능을 추가한다.

이 로직은 모든 주택에 동일하므로 Dwelling (SuperClass) 에서 함수를 구현할 수 있고, 이를 통해 모든 서브클래스그 하위 요소에서 함수를 사용할 수 있도록 한다.

최상위 Class 인 Dwelling 에 , getRoom() 함수를 추가한다.

capa가 residents보다 많으면, residents를 +1 한다. 

abstract class Dwelling(private var residents: Int) {
    abstract val buildingMaterial: String
    abstract val capacity: Int
    
    fun hasRoom(): Boolean {
        return residents < capacity
    }
    abstract fun floorArea(): Double
    
    // getRoom 함수 추가. 
    fun getRoom() {
        if (capacity > residents) {
            residents++
            println("You got a room!")
        } else {
            println("Sorry, at capacity and no rooms left.!")
        }
    }
}

이렇게 쓴 뒤에, main() 함수 내에서, Dwelling의 하위 클래스 중 하나인, RoundHut 의 with 블록에 

아래의 소스를 추가해봅니다.

println("Has room? ${hasRoom()}")
getRoom()
println("Has room? ${hasRoom()}")
getRoom()

그러면 아래와 같은 결과가 나온다.

Has room? true
You got a room!
Has room? false
Sorry, at capacity and no rooms left.

 

이번 실습은, 상속이 매우 강력한 이유를 보여준다. 

Dwelling (최상위 클래스) 모든 서브클래스에서 이러한 하위 클래스에 코드를 추가하지 않고도 getRoom() 함수를 호출할 수 있습니다.

 

추가로, RoundHut이나 RoundTower에 서 사용할 카펫 사이즈를 알아보기 위한 함수를 추가해 보자.

이 경우는, SubClass에서 함수를 넣을시에 그 아래의 class까지 사용할 수 있는 것을 보여주기 위한 예시이다.

** (Dwelling -> RoundHut -> RoundTower ) 에서 RoundHut 에 함수를 넣으면 RoundTower에서도 사용할수 있다는 말!

fun calculateMaxCarpetSize(): Double {
        val diameter = 2 * radius
        return kotlin.math.sqrt(diameter * diameter / 2)
    }

요 함수를 RoundHut에 집어넣고, 

main()에서 RoundHut과 RoundTower with 블록에서 사용하면 둘다 정상 동작한다. (값이 출력된다. 

 

** 오늘 실습 최종 소스 코드 ** 

더보기
fun main() {
    val squareCabin = SquareCabin(6, 50.0)
    val roundHut = RoundHut(3, 10.0)
    val roundTower = RoundTower(4, 15.5)
    /*
    println("\n Square Cabin\n=========")
    println("Capacity: ${squareCabin.capacity}")
    println("Material: ${squareCabin.buildingMaterial}")
    println("Has room? ${squareCabin.hasRoom()}")
    */
    with(squareCabin) {
        println("\n Square Cabin \n=======")
        println("Capacity: ${capacity}")
        println("Material: ${buildingMaterial}")
        println("floorArea: ${floorArea()}")
        println("Has Room? ${hasRoom()}")
    }
    
    with(roundHut) {
        println("\n Round Hut \n=======")
        println("Capacity: ${capacity}")
        println("Material: ${buildingMaterial}")
        println("floorArea: ${floorArea()}")
        println("Has Room? ${hasRoom()}")
        getRoom()
        println("Has Room? ${hasRoom()}")
        getRoom()
        println("Carpet Size? ${calculateMaxCarpetSize()}")
    }
    with(roundTower) {
        println("\n Round Hut \n=======")
        println("Capacity: ${capacity}")
        println("Material: ${buildingMaterial}")
        println("floorArea: ${floorArea()}")
        println("Carpet Size? ${calculateMaxCarpetSize()}")
    }
}

abstract class Dwelling(private var residents: Int) {
    abstract val buildingMaterial: String
    abstract val capacity: Int
    
    fun hasRoom(): Boolean {
        return residents < capacity
    }
    abstract fun floorArea(): Double
    
    fun getRoom() {
        if (capacity > residents) {
            residents++
            println("You got a room!")
        } else {
            println("Sorry, at capacity and no rooms left.!")
        }
    }
}

class SquareCabin(residents: Int, val length: Double) : Dwelling(residents) {
    override val buildingMaterial = "Wood"
    override val capacity = 6
    
    override fun floorArea(): Double {
        return length * length
    }
}

open class RoundHut(residents: Int,
                   val radius: Double) : Dwelling(residents) {
    override val buildingMaterial = "Straw"
    override val capacity = 4
    
    override fun floorArea(): Double {
        return radius * radius
    }
    
    fun calculateMaxCarpetSize(): Double {
        val diameter = 2 * radius
        return kotlin.math.sqrt(diameter * diameter / 2)
    }
}

class RoundTower(residents: Int, 
                 radius: Double,
                 val floors: Int = 2) : RoundHut(residents, radius) {
    override val buildingMaterial = "Stone"
    override val capacity = 4 * floors
    /*
    override fun floorArea(): Double {
        return radius * radius * floors
    }
    */
    override fun floorArea(): Double{
        return super.floorArea() * floors
    }
}

 


최종 핵심 정리 

  • 하위 클래스가 상위 클래스에서 기능을 상속받는 클래스 트리인 클래스 계층 구조를 만드는 방법. 속성과 함수가 서브클래스에 상속됩니다.
  • 일부 기능을 서브클래스에서 구현하도록 남기는 abstract 클래스를 만드는 방법. 따라서 abstract 클래스는 인스턴스화할 수 없습니다.
  • abstract 클래스의 서브클래스를 만드는 방법
  • override 키워드를 사용하여 서브클래스의 속성과 함수를 재정의하는 방법
  • super 키워드를 사용하여 상위 클래스의 함수와 속성을 참조하는 방법
  • 서브클래스로 분류할 수 있도록 클래스를 open으로 만드는 방법
  • 속성을 private으로 만들어 클래스 내에서만 사용할 수 있도록 하는 방법
  • with 구문을 사용하여 동일한 객체 인스턴스에서 여러 호출을 실행하는 방법
  • kotlin.math 라이브러리에서 기능을 가져오는 방법
728x90
반응형

'IT > 안드로이드' 카테고리의 다른 글

Kotlin - List, MutableList  (6) 2022.04.20
Android - Material Design page  (2) 2022.04.19
Kotlin의 클래스 및 상속 - 2  (1) 2022.04.18
Kotlin 의 Class 및 상속  (2) 2022.04.18
Android - Kotlin Logging & Debugging  (3) 2022.04.15