ある型Baseを引数に取るようなコンテクストで他の型のインスタンスを使おうとすると、当然、通常ならばコンパイラがエラーを吐く。
//example class DrinkContent(receipt: String) { val receiptVal = receipt def drink = {System.out.println(receiptVal)} } class PetBottle(content: DrinkContent) { var contentVal = content } REPL> new DrinkContent("Orange") .drink // "Orange" REPL> new PetBottle(new DrinkContent("Apple")) .drink // Error: drinkメソッドはPetBottleには存在しない
このように、ある型を暗黙に別の型に変換したいときがある。
implicit defはこの問題を解決する。
implicitを付けてdefされた関数は、変換前の型のインスタンスから変換後の型のインスタンスへの変換を自動的に行なうためのハンドラのようにふるまう。
このテクニックにより、instance.getXX()のような処理を隠匿することができる。
ただし使いすぎると変換を追えなくなりバグのもとなので使用はほどほどに。
//example class DrinkContent(receipt: String) { val receiptVal: String = receipt def drink = {System.out.println(receiptVal)} } class PetBottle(content: DrinkContent) { var contentVal: DrinkContent = content } implicit def PetBottle2DrinkContent(pet: PetBottle): DrinkContent = pet.contentVal REPL> val OrangeJuiceBottle = new PetBottle(new DrinkContent("Orange")) REPL> OrangeJuiceBottle.drink // "Orange": 自動的にPetBottle2DrinkContentが呼び出され、DrinkContentのdrinkが呼ばれる
このテクニックは、既存のSealed属性のクラスに新たな機能を追加するときにも使用できる。