抽象クラス・継承

  • 投稿者:
  • 投稿カテゴリー:その他

抽象クラス、サブクラス、openキーワード

・抽象クラス
完全に実装されていないため、インスタンス化できないクラス
abstract class クラス名 () { }

・サブクラス
抽象クラスや他のクラスを継承した子クラス
class クラス名() : 親クラス名() { }

・openキーワード付のクラスは抽象クラスでなくても親クラスになれる
open class クラス名() : 型 { }

import kotlin.math.PI
import kotlin.math.sqrt

fun main() {
    val squareCabin = SquareCabin(6, 50.0)	// 抽象クラスのインスタンス化1
    val roundHut = RoundHut(3, 10.0)		// 抽象クラスのインスタンス化2
    val roundTower = RoundTower(4, 15.5)	// open key word付きのクラスをインスタンス化

    // 結果の確認
    with(squareCabin) {
       println("\nSquare Cabin\n============")
       println("Capacity: ${capacity}")
       println("Material: ${buildingMaterial}")
       println("Floor area: ${floorArea()}")
   }

   with(roundHut) {
       println("\nRound Hut\n=========")
       println("Material: ${buildingMaterial}")
       println("Capacity: ${capacity}")
       println("Floor area: ${floorArea()}")
       println("Has room? ${hasRoom()}")
       getRoom()
       println("Has room? ${hasRoom()}")
       getRoom()
       println("Carpet size: ${calculateMaxCarpetSize()}")
   }

   with(roundTower) {
       println("\nRound Tower\n==========")
       println("Material: ${buildingMaterial}")
       println("Capacity: ${capacity}")
       println("Floor area: ${floorArea()}")
       println("Carpet size: ${calculateMaxCarpetSize()}")
   }
}

// 抽象クラスの例
abstract class Dwelling(private var residents: Int) {

    // 抽象クラスの変数にabstractを付加
    // 子クラスではabstract変数や関数を必ずoverrideする
    abstract val buildingMaterial: String
    abstract val capacity: Int    

    // 抽象関数の例(abstractを付加)
    abstract fun floorArea(): Double


    // 関数の例1
    fun hasRoom(): Boolean {
        return residents < capacity
    }
    
    // 関数の例2
    // 人数を追加できるか判定する関数(全ての子クラスで利用可能)
    fun getRoom() {
       if (capacity > residents) {
           residents++
           println("You got a room!")
       } else {
           println("Sorry, at capacity and no rooms left.")
       }
   }
}


// サブクラスの例(openキーワードが無いのでfinalとなる)
class SquareCabin(residents: Int,
    val length: Double) : Dwelling(residents) {

    // 抽象クラスで宣言した変数に値を設定
    override val buildingMaterial = "Wood"
    override val capacity = 6

    // 抽象関数をoverride
    override fun floorArea(): Double {
       return length * length
    }
}

// openキーワード付のサブクラスの例
open class RoundHut(val residents: Int,
    val radius: Double) : Dwelling(residents) {
    
    override val buildingMaterial = "Straw"
    override val capacity = 4
   
    // 抽象関数をoverride
    override fun floorArea(): Double {
        return PI * radius * radius
    }
    
   fun calculateMaxCarpetSize(): Double {
       val diameter = 2 * radius
       return sqrt(diameter * diameter / 2)
   }
}

// サブクラスの例(openキーワードのクラスを継承)
class RoundTower(residents: Int, radius: Double,
    val floors: Int = 2) : RoundHut(residents, radius) {

    override val buildingMaterial = "Stone"
    override val capacity = 4 * floors
    
    // 抽象関数をoverride
    override fun floorArea(): Double {
        // この場合親関数の結果をsuper.floorArea()として取得
        return super.floorArea() * floors
    }
}

トレーニング > KOTLIN を用いた ANDROID の基本 > レイアウト > ユーザー入力1 > Kotlin のクラスと継承 > 4.サブクラスを作成する