本記事では「バケツ」のオブジェクトを取り扱う
- データ
- 容量
- 現在の水量
- 振る舞い
- 水で満たす
- 排水する
- 入っている水量を出力
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)