← Back to Kotlin Course | Chapter 7: Inheritance & Interfaces | Lesson 7 of 7

by के साथ Delegation

by keyword किसी class को यह कहने देता है 'इस ability के लिए, बस सारा काम इस दूसरे object को forward कर दो जो मेरे पास पहले से है', खुद logic लिखने के बजाय।
Syntax
kotlin
interface InterfaceName {
    fun method()
}

class ClassName(impl: InterfaceName) : InterfaceName by impl {
    // members forwarded to impl; override any you want to change
}

Delegating an Interface with by

किसी class header के बाद : Interface by someObject लिखना उस interface के members की हर call को अपने आप someObject को forward कर देता है, बिना हाथ से कोई forwarding code लिखे।

उदाहरण: Delegating an Interface with by

markup
// Define an interface `Printer` describing required behavior
interface Printer {
    // Define the function `printMessage` taking `message`
    fun printMessage(message: String)
}

// Define a class `ConsolePrinter`
class ConsolePrinter : Printer {
    override fun printMessage(message: String) {
        // Print "Console: $message" to the console, with a trailing newline
        println("Console: $message")
    }
}

// Define a class `App`
class App(printer: Printer) : Printer by printer

// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `app`, set to `App(ConsolePrinter())`
    val app = App(ConsolePrinter())
    app.printMessage("Hello via delegation")
}

Overriding a Delegated Member

किसी interface को delegate करने के लिए by उपयोग करते समय भी, कोई class अब भी किसी specific member को खुद override कर सकती है, और वह override forwarded implementation से प्राथमिकता लेता है।

उदाहरण: Overriding a Delegated Member

markup
// Define an interface `Printer` describing required behavior
interface Printer {
    // Define the function `printMessage` taking `message`
    fun printMessage(message: String)
}

// Define a class `ConsolePrinter`
class ConsolePrinter : Printer {
    override fun printMessage(message: String) {
        // Print "Console: $message" to the console, with a trailing newline
        println("Console: $message")
    }
}

// Define a class `LoudApp`
class LoudApp(printer: Printer) : Printer by printer {
    override fun printMessage(message: String) {
        // Print "LOUD: ${message.toUpperCase()}" to the console, with a trailing newline
        println("LOUD: ${message.toUpperCase()}")
    }
}

// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `app`, set to `LoudApp(ConsolePrinter())`
    val app = LoudApp(ConsolePrinter())
    app.printMessage("hello")
}

Why Use Delegation

Delegation manually हर interface member को forward करने की formalities से बचाता है, जबकि फिर भी किसी class को सिर्फ inheritance पर निर्भर रहने के बजाय किसी दूसरे object से behavior compose करने देता है।

उदाहरण: Why Use Delegation

markup
// Define an interface `Repository` describing required behavior
interface Repository {
    // Define the function `getAll` with no parameters and returning a `List<String>`
    fun getAll(): List<String>
}

// Define a class `InMemoryRepository`
class InMemoryRepository(private val items: List<String>) : Repository {
    override fun getAll(): List<String> = items
}

// Define a class `CachedRepository`
class CachedRepository(repo: Repository) : Repository by repo

// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `repo`, set to `CachedRepository(InMemoryRepository(listOf("a", "b", "c")))`
    val repo = CachedRepository(InMemoryRepository(listOf("a", "b", "c")))
    // Print `repo.getAll()` to the console, with a trailing newline
    println(repo.getAll())
}

Property Delegation with by lazy

वही by keyword property delegation के लिए भी उपयोग होता है, lazy { ... } सबसे आम built-in delegate होने के साथ -- यह सिर्फ property के पहली बार access होने पर एक value compute और cache करता है।

Note: देखें "Computing value..." सिर्फ एक बार print होता है, भले ही property दो बार पढ़ी गई हो।

उदाहरण: Property Delegation with by lazy

markup
val expensiveValue: String by lazy {
    // Print "Computing value..." to the console, with a trailing newline
    println("Computing value...")
    "Computed Result"
}

// Entry point: execution of the program starts here
fun main() {
    // Print "Before access" to the console, with a trailing newline
    println("Before access")
    // Print `expensiveValue` to the console, with a trailing newline
    println(expensiveValue)
    // Print `expensiveValue` to the console, with a trailing newline
    println(expensiveValue)
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. Kotlin के built-in by delegation का उपयोग करने के बजाय किसी internal object को calls forward करने के लिए हाथ से किसी interface के हर method को फिर से implement करना।
  2. यह भूल जाना कि by के साथ, delegating class में एक specific method को override करना अब भी बाकी को delegate को अपने आप forward होने देता है।
  3. interface delegation (किसी class header में किसी interface के बाद by) को property delegation (किसी property पर by, जैसे lazy) के साथ confuse करना, जो संबंधित लेकिन अलग features हैं।
चैप्टर सारांश
  • class MyClass(val impl: Interface) : Interface by impl हर interface member को अपने आप impl को forward करता है।
  • यह hाथ से बार-बार forwarding methods लिखने से बचाता है, एक pattern जिसे delegation pattern कहा जाता है।
  • Specific methods अब भी delegating class में override किए जा सकते हैं, forwarded implementation से प्राथमिकता लेते हुए।
  • Property delegation, जैसे val x by lazy { ... }, by keyword का एक संबंधित लेकिन अलग उपयोग है।
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.