Bird
Raised Fist0
Kotlinprogramming~20 mins

Why delegation avoids inheritance in Kotlin - Challenge Your Understanding

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Delegation Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of delegation vs inheritance example
What is the output of this Kotlin code that uses delegation instead of inheritance?
Kotlin
interface Printer {
    fun print()
}

class RealPrinter : Printer {
    override fun print() {
        println("Printing from RealPrinter")
    }
}

class Delegator(printer: Printer) : Printer by printer

fun main() {
    val realPrinter = RealPrinter()
    val delegator = Delegator(realPrinter)
    delegator.print()
}
ARuntime error: NullPointerException
BPrinting from Delegator
CCompilation error due to delegation
DPrinting from RealPrinter
Attempts:
2 left
💡 Hint
Delegation forwards calls to the object it delegates to.
🧠 Conceptual
intermediate
1:30remaining
Why delegation avoids tight coupling
Which reason best explains why delegation avoids tight coupling compared to inheritance?
ADelegation allows changing behavior at runtime by swapping delegate objects.
BDelegation forces all subclasses to share the same implementation.
CDelegation requires the subclass to override all methods explicitly.
DDelegation prevents code reuse across classes.
Attempts:
2 left
💡 Hint
Think about flexibility in changing behavior without changing class hierarchy.
🔧 Debug
advanced
2:00remaining
Identify the error in delegation usage
What error will this Kotlin code produce and why?
Kotlin
interface Speaker {
    fun speak()
}

class Person : Speaker {
    override fun speak() {
        println("Hello")
    }
}

class Robot(speaker: Speaker) : Speaker by speaker {
    fun speak() {
        println("Robot speaking")
    }
}

fun main() {
    val person = Person()
    val robot = Robot(person)
    robot.speak()
}
APrints 'Hello'
BPrints 'Robot speaking'
CCompilation error: 'speak' overrides nothing
DRuntime error: StackOverflowError
Attempts:
2 left
💡 Hint
Check which speak() method is called on robot.
❓ Predict Output
advanced
2:00remaining
Output when delegation changes delegate at runtime
What is the output of this Kotlin code that changes the delegate object at runtime?
Kotlin
interface Worker {
    fun work()
}

class Developer : Worker {
    override fun work() {
        println("Writing code")
    }
}

class Tester : Worker {
    override fun work() {
        println("Testing code")
    }
}

class Manager(var worker: Worker) : Worker by worker {
    fun changeWorker(newWorker: Worker) {
        worker = newWorker
    }
}

fun main() {
    val dev = Developer()
    val test = Tester()
    val manager = Manager(dev)
    manager.work()
    manager.changeWorker(test)
    manager.work()
}
A
Writing code
Testing code
BCompilation error: delegation cannot be changed
C
Writing code
Writing code
D
Testing code
Testing code
Attempts:
2 left
💡 Hint
Delegation is set at object creation and does not change when the delegate variable changes.
🧠 Conceptual
expert
2:30remaining
Why delegation is preferred over inheritance for code reuse
Which statement best explains why delegation is often preferred over inheritance for code reuse in Kotlin?
ADelegation allows combining behaviors from multiple sources without a rigid class hierarchy.
BDelegation forces all subclasses to inherit from a single parent class.
CDelegation prevents any form of polymorphism.
DDelegation requires less code but cannot be used with interfaces.
Attempts:
2 left
💡 Hint
Think about flexibility and combining behaviors.

Practice

(1/5)
1. Why does Kotlin prefer delegation over inheritance in many cases?
easy
A. Inheritance is not supported in Kotlin.
B. Delegation requires less code than inheritance.
C. Delegation allows sharing behavior without tightly coupling classes.
D. Delegation makes classes run faster.

Solution

  1. Step 1: Understand inheritance coupling

    Inheritance creates a strong link between parent and child classes, making changes harder.
  2. Step 2: Understand delegation flexibility

    Delegation shares behavior by forwarding calls, avoiding tight coupling and allowing easier changes.
  3. Final Answer:

    Delegation allows sharing behavior without tightly coupling classes. -> Option C
  4. Quick Check:

    Delegation avoids tight coupling = A [OK]
Hint: Delegation shares behavior without tight class links [OK]
Common Mistakes:
  • Thinking delegation is faster than inheritance
  • Believing Kotlin does not support inheritance
  • Confusing delegation with less code requirement
2. Which Kotlin syntax correctly shows delegation to an interface Printer by a class Document?
easy
A. class Document(printer: Printer) : Printer by printer
B. class Document : Printer(printer)
C. class Document implements Printer by printer
D. class Document extends Printer by printer

Solution

  1. Step 1: Recall Kotlin delegation syntax

    Kotlin uses class ClassName(...) : Interface by instance to delegate.
  2. Step 2: Match syntax to options

    class Document(printer: Printer) : Printer by printer matches the correct Kotlin delegation syntax exactly.
  3. Final Answer:

    class Document(printer: Printer) : Printer by printer -> Option A
  4. Quick Check:

    Delegation syntax uses ': Interface by instance' = B [OK]
Hint: Look for ': Interface by instance' syntax in Kotlin delegation [OK]
Common Mistakes:
  • Using 'implements' or 'extends' keywords (Java style)
  • Placing delegation inside parentheses incorrectly
  • Confusing inheritance syntax with delegation
3. What is the output of this Kotlin code?
interface Logger {
    fun log(msg: String)
}

class ConsoleLogger : Logger {
    override fun log(msg: String) {
        println("Console: $msg")
    }
}

class FileLogger : Logger {
    override fun log(msg: String) {
        println("File: $msg")
    }
}

class Application(logger: Logger) : Logger by logger

fun main() {
    val app = Application(ConsoleLogger())
    app.log("Start")
}
medium
A. File: Start
B. Console: Start
C. Application: Start
D. No output

Solution

  1. Step 1: Identify delegated logger instance

    The Application class delegates Logger to the passed instance, here ConsoleLogger.
  2. Step 2: Trace the log call

    Calling app.log("Start") calls ConsoleLogger.log, printing "Console: Start".
  3. Final Answer:

    Console: Start -> Option B
  4. Quick Check:

    Delegation calls ConsoleLogger.log = A [OK]
Hint: Delegation calls methods on passed instance, check which one is used [OK]
Common Mistakes:
  • Assuming FileLogger is used instead of ConsoleLogger
  • Expecting Application prefix in output
  • Thinking no output occurs without explicit print
4. Find the error in this Kotlin delegation code:
interface Worker {
    fun work()
}

class Engineer : Worker {
    override fun work() {
        println("Engineering work")
    }
}

class Manager(worker: Worker) : Worker {
    override fun work() {
        println("Managing")
    }
}
medium
A. Manager should delegate work to Worker using 'by' keyword.
B. Engineer class must not override work method.
C. Interface Worker cannot be implemented by classes.
D. Manager class should not have a constructor parameter.

Solution

  1. Step 1: Check delegation usage

    Manager has a Worker parameter but does not delegate using 'by', so delegation is missing.
  2. Step 2: Identify correct delegation syntax

    To delegate, Manager should declare: class Manager(worker: Worker) : Worker by worker.
  3. Final Answer:

    Manager should delegate work to Worker using 'by' keyword. -> Option A
  4. Quick Check:

    Missing 'by' keyword for delegation = D [OK]
Hint: Delegation requires ': Interface by instance' syntax [OK]
Common Mistakes:
  • Thinking override is not needed in Engineer
  • Believing interfaces can't be implemented
  • Assuming constructor parameters are disallowed
5. You want to combine behaviors of two interfaces Reader and Writer in one class without inheritance. Which Kotlin approach best avoids inheritance problems?
hard
A. Copy all methods from Reader and Writer into one class manually.
B. Create a class that inherits from both interfaces directly.
C. Use inheritance from one interface and implement the other manually.
D. Use delegation to both interfaces by passing separate instances.

Solution

  1. Step 1: Understand multiple inheritance issues

    Inheriting from multiple interfaces can cause tight coupling and complexity.
  2. Step 2: Use delegation to combine behaviors safely

    Delegation allows combining behaviors by forwarding calls to separate instances, avoiding inheritance problems.
  3. Final Answer:

    Use delegation to both interfaces by passing separate instances. -> Option D
  4. Quick Check:

    Delegation combines behaviors safely = C [OK]
Hint: Delegate multiple interfaces to separate instances to avoid inheritance issues [OK]
Common Mistakes:
  • Trying multiple inheritance which Kotlin disallows
  • Manually copying methods causing code duplication
  • Mixing inheritance and manual implementation causing complexity
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard