メンバーへの委譲
動作を合成します
「メンバーへの委譲」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
振る舞いを組み立てる
実際のオブジェクトでは、複数の機能を組み合わせる必要があることがよくあります。複数のクラスを継承する代わりに、各機能を専用のメンバーオブジェクトに委譲できます。
2つの役割を1つのクラスで担う
あるクラスに読み取りと書き込みの両方を担わせるとします。2つのインターフェースを定義し、それぞれを別の実装に委譲します。
interface Reader { fun read(): String }
interface Writer { fun write(s: String): String }
class FileReader : Reader { override fun read() = "contents" }
class FileWriter : Writer { override fun write(s: String) = "wrote " + s }
class FileIO(r: Reader, w: Writer) : Reader by r, Writer by w
fun main() {
val io = FileIO(FileReader(), FileWriter())
println(io.read())
println(io.write("data"))
}複数の委譲先
1つのクラスから複数のインターフェースを同時に委譲し、それぞれを異なるメンバーに任せることができます。クラスは継承せずに、それらの振る舞いを組み合わせられます。
interface Logger { fun log(m: String): String }
interface Validator { fun valid(m: String): Boolean }
class ConsoleLogger : Logger { override fun log(m: String) = "LOG: " + m }
class LengthValidator : Validator { override fun valid(m: String) = m.isNotEmpty() }
class Service(l: Logger, v: Validator) : Logger by l, Validator by v
fun main() {
val s = Service(ConsoleLogger(), LengthValidator())
println(s.valid("hi"))
println(s.log("started"))
}委譲先をメンバーとして保持する
オーバーライドした処理の中で委譲先を参照する必要がある場合は、コンストラクタープロパティとして保持します。同じインスタンスが転送処理と独自のコードの両方で使われます。
interface Cache { fun get(k: String): String }
class MapCache : Cache {
override fun get(k: String) = "value-of-" + k
}
class TracingCache(private val inner: Cache) : Cache by inner {
override fun get(k: String): String {
println("lookup " + k)
return inner.get(k)
}
}
fun main() {
println(TracingCache(MapCache()).get("id"))
}委譲と独自の状態を組み合わせる
委譲するクラスには、転送されたメンバーに加えて、独自のプロパティやメソッドを追加できます。これにより、組み合わせたオブジェクトをさらに拡張できます。
interface Engine { fun start(): String }
class V8 : Engine { override fun start() = "vroom" }
class Car(e: Engine) : Engine by e {
var doors = 4
fun honk() = "beep"
}
fun main() {
val c = Car(V8())
println(c.start())
println(c.honk())
println(c.doors)
}実装を差し替える
委譲先は単なるメンバーなので、異なる基盤実装を使って同じラッパーを構築し、実行時に振る舞いを選べます。
interface Notifier { fun send(msg: String): String }
class EmailNotifier : Notifier { override fun send(msg: String) = "email: " + msg }
class SmsNotifier : Notifier { override fun send(msg: String) = "sms: " + msg }
class Alerts(n: Notifier) : Notifier by n
fun main() {
println(Alerts(EmailNotifier()).send("hi"))
println(Alerts(SmsNotifier()).send("hi"))
}プロパティへの委譲
byの後の式には、コンストラクター呼び出しを含め、1回評価される任意の式を指定できます。パラメーターである必要はありません。
interface Greeter { fun greet() = "hi" }
class DefaultGreeter : Greeter
class Page : Greeter by DefaultGreeter()
fun main() {
println(Page().greet())
}ダイヤモンド問題を避ける
クラスでは振る舞いの多重継承はできません。しかし、複数のインターフェースをそれぞれ別のメンバーに委譲すれば、典型的なダイヤモンド問題をきれいに回避できます。
interface A { fun a() = "A" }
interface B { fun b() = "B" }
class AImpl : A
class BImpl : B
class Combined : A by AImpl(), B by BImpl()
fun main() {
val c = Combined()
println(c.a() + c.b())
}コンポジションを前提に設計する
うまく組み合わせるには、次のようにします。
- 小さく、役割を絞ったインターフェースを定義する
- 再利用可能な実装を用意する
- 組み合わせるクラスで各役割を委譲する
これにより、クラスの柔軟性とテストのしやすさを保てます。
メンバー委譲のまとめ
メンバーオブジェクトへの委譲を使うと、クラスは複数の部品から振る舞いを組み立てられます。継承を使わずに、多数のインターフェースを組み合わせ、一部だけをオーバーライドし、実装を差し替え、独自の状態を追加できます。
次は、直接比較します
委譲がどれほど柔軟かを見てきました。次のレッスンでは、委譲と継承を直接比較し、それぞれをいつ選ぶべきかを学びます。
理解度チェック
メンバーへの委譲についての理解度を確認しましょう。
まとめ
メンバー委譲について、次のことを学びました。
- 複数のインターフェースを別々のオブジェクトに委譲する
- 一部だけをオーバーライドし、独自の状態を追加する
- 構築時に実装を差し替える
- 多重継承に伴う問題を避ける
次は、委譲と継承を比較します。
AI チューターと学ぶ Kotlin — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 51
- レッスン
- 203
よくある質問
「メンバーへの委譲」レッスンは無料ですか?
はい。「メンバーへの委譲」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「メンバーへの委譲」で何を学びますか?
動作を合成します ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「メンバーへの委譲」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。