LoginSignup
1
0

More than 5 years have passed since last update.

Kotlinまとめ - 文法詳解 - オブジェクトからクラスへ

Last updated at Posted at 2018-07-16

本記事では「バケツ」のオブジェクトを取り扱う

  • データ
    • 容量
    • 現在の水量
  • 振る舞い
    • 水で満たす
    • 排水する
    • 入っている水量を出力
val bucket = object {
    val capacity: Int = 5

    // 現在の水量
    var quantity: Int = 0

    // バケツを水で満たす
    fun fill() {
        quantity = capacity
    }

    // 排水する
    fun drainAway() {
        quantity = 0
    }

    // 入っている水量を出力
    fun printQuantity() {
        println(quantity)
    }
}

インタフェース

  • このバケツオブジェクトはデータ型を持っておらず、実用には耐えない。(正確には型はあるが型名による参照ができない)
  • インタフェースにより型を定義する
interface Bucket

val bucket = object: Bucket {
    // バケツの容量
    val capacity: Int = 5

    // 現在の水量
    var quantity: Int = 0

    // バケツを水で満たす
    fun fill() {
        quantity = capacity
    }

    // 排水する
    fun drainAway() {
        quantity = 0
    }

    // 入っている水量を出力
    fun printQuantity() {
        println(quantity)
    }

    // 他のバケツに注ぐ
    // インタフェースを定義したことで、同様のインタフェースをもつオブジェクトを扱えるようになった
    fun pourTo(that: Bucket) {
        // 未実装
    }
}
  • Bucketインタフェースに必要な実装を移す
    • 容量と現在の水量はgetter, setterを定義
    • printQuantity()は削除
    • Bucketを生成するメソッドを定義
  • インタフェースに定義されているメソッドを実装するときはoverrideキーワードをつける
interface Bucket {
    fun fill()
    fun drainAway()
    fun pourTo(that: Bucket)

    fun getCapacity(): Int
    fun getQuantity(): Int
    fun setQuantity(quantity: Int)
}

fun createBucket(capacity: Int): Bucket = object: Bucket {

    var _quantity: Int = 0

    override fun fill() {
        setQuantity(getCapacity())
    }

    override fun drainAway() {
        setQuantity(0)
    }

    override fun pourTo(that: Bucket) {
        val thatVacuity = that.getCapacity() - that.getQuantity()
        if (getQuantity() <= thatVacuity) {
            that.setQuantity(that.getQuantity() + getQuantity())
            drainAway()
        } else {
            that.fill()
            setQuantity(getQuantity() - thatVacuity)
        }
    }

    override fun getCapacity(): Int = capacity

    override fun getQuantity(): Int = _quantity

    override fun setQuantity(quantity: Int) {
        _quantity = quantity
    }
}

プロパティ

容量と現在の水量をプロパティで表現すると

interface Bucket {
    val capacity: Int
    var quantity: Int

    fun fill()
    fun drainAway()
    fun pourTo(that: Bucket)
}

fun createBucket(_capacity: Int): Bucket = object: Bucket {

    override val capacity: Int = _capacity

    override var quantity: Int = 0

    override fun fill() {
        quantity = capacity
    }

    override fun drainAway() {
        quantity = 0
    }

    override fun pourTo(that: Bucket) {
        val thatVacuity = that.capacity - that.quantity
        if (quantity <= thatVacuity) {
            that.quantity += quantity
            drainAway()
        } else {
            that.fill()
            quantity -= thatVacuity
        }
    }
}

クラス

  • コンストラクタ経由で生成
  • 継承や拡張など、強力な仕組みを使えるようになる
class BucketImpl(_capacity: Int): Bucket {

    override val capacity: Int = _capacity

    override var quantity: Int = 0

    override fun fill() {
        quantity = capacity
    }

    override fun drainAway() {
        quantity = 0
    }

    override fun pourTo(that: Bucket) {
        val thatVacuity = that.capacity - that.quantity
        if (quantity <= thatVacuity) {
            that.quantity += quantity
            drainAway()
        } else {
            that.fill()
            quantity -= thatVacuity
        }
    }
}

val bucket: Bucket = BucketImpl(1)

← 文法詳解 - 第一級オブジェクトとしての関数 || 文法詳解 - クラスとそのメンバ →

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0