class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
Slide 31
Slide 31 text
class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
インタフェースを実装
Slide 32
Slide 32 text
class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
このへんがコンポジション:
実装を継承するのではなく、
実装を保持する。
Slide 33
Slide 33 text
class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
さっきと同じ
Slide 34
Slide 34 text
class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
その他のコードは省略
Slide 35
Slide 35 text
試してみる
val set = CountingSet(HashSet())
set.add(1)
set.add(2)
println(set.addCount) // 2
set.addAll(setOf(3, 4, 5))
println(set.addCount) // 期待通りの5
実装をコンストラクタで渡す
Slide 36
Slide 36 text
class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
その他のコードは省略
Slide 37
Slide 37 text
class CountingSet(private val set: MutableSet)
: MutableSet {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
...
他にオーバライドすべきメソッドたち
Slide 38
Slide 38 text
override val size: Int get() = set.size
override fun contains(element: E): Boolean =
set.contains(element)
override fun remove(element: E): Boolean = set.remove(element)
override fun containsAll(elements: Collection): Boolean =
set.containsAll(elements)
override fun isEmpty(): Boolean = set.isEmpty()
override fun clear() { set.clear() }
override fun iterator(): MutableIterator = set.iterator()
override fun removeAll(elements: Collection): Boolean =
set.removeAll(elements)
override fun retainAll(elements: Collection): Boolean =
set.retainAll(elements)
他にオーバライドすべきメソッドたち
Slide 39
Slide 39 text
override val size: Int get() = set.size
override fun contains(element: E): Boolean =
set.contains(element)
override fun remove(element: E): Boolean = set.remove(element)
override fun containsAll(elements: Collection): Boolean =
set.containsAll(elements)
override fun isEmpty(): Boolean = set.isEmpty()
override fun clear() { set.clear() }
override fun iterator(): MutableIterator = set.iterator()
override fun removeAll(elements: Collection): Boolean =
set.removeAll(elements)
override fun retainAll(elements: Collection): Boolean =
set.retainAll(elements)
他にオーバライドすべきメソッドたち
めんど
くさい!
Slide 40
Slide 40 text
4. Class Delegation
Slide 41
Slide 41 text
class CountingSet(private val set: MutableSet)
: MutableSet by set {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
}
Slide 42
Slide 42 text
class CountingSet(private val set: MutableSet)
: MutableSet by set {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
}
このおまじないが
Class Delegation
Slide 43
Slide 43 text
class CountingSet(private val set: MutableSet)
: MutableSet by set {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
}
ここは依然変わらず
Slide 44
Slide 44 text
class CountingSet(private val set: MutableSet)
: MutableSet by set {
var addCount: Int = 0
private set
override fun add(element: E): Boolean {
addCount++
return set.add(element)
}
override fun addAll(elements: Collection): Boolean {
addCount += elements.size
return set.addAll(elements)
}
}
他にオーバライドすべきメソッドたち
を明示的に記述する必要がない!
Slide 45
Slide 45 text
試してみる(コードはさっきと同じ)
val set = CountingSet(HashSet())
set.add(1)
set.add(2)
println(set.addCount) // 2
set.addAll(setOf(3, 4, 5))
println(set.addCount) // 期待通りの5
Slide 46
Slide 46 text
まとめ
● 実装の継承には十分注意する
● インタフェースに依存し、実装は外部から注入
● Class Delegationを使うと、簡単に記述できる