'Useless Kotlin delegate

I'm trying to understand why we have feature as delegate in Kotlin. This example is similar to wiki example https://en.wikipedia.org/wiki/Delegation_pattern

Check this commented fragment, I don't need it for using area function on bounds so why we should use : ClosedShape by bounds ?

interface ClosedShape {
    fun area(): Int
}

class Rectangle(val width: Int, val height: Int) : ClosedShape {
    override fun area() = width * height
}

class Window(private val bounds: ClosedShape)  /*: ClosedShape by bounds */ {
    init {
        bounds.area()
    }
}


Solution 1:[1]

I don't need it for using area function on bounds

The point is not about whether you can use area on bounds or not. Sure, if all you want to do is to call bounds.area(), you don't need : ClosedShape by bounds.

Here's a little hypothetical situation, based on ClosedShape and Window, where using the by syntax to implement an interface is helpful.

Notice how a Window is bounded by a Rectangle. Wouldn't it make sense for Window to also be a ClosedShape? If we have a function that works on ClosedShape, wouldn't it be nice if we can directly pass a Window to it, rather than passing window.bounds?

fun printArea(shape: ClosedShape) { 
    println(shape.area())
}

// we could write this:
printArea(window)

// rather than:
printArea(window.bounds)

This would mean that Window would implement ClosedShape. We could implement it without using a delegate:

class Window(private val bounds: ClosedShape) : ClosedShape {
    override fun area() = bounds.area()
}

But that would be very tedious if ClosedShape had many more methods than area. Imagine having to implement 20 methods, all of which just calls that same method on bounds:

class Window(private val bounds: ClosedShape) : ClosedShape {
    override fun area() = bounds.area()
    override fun perimeter() = bounds.perimeter()
    override fun numberOfSides() = bounds.numberOfSides()
    override fun isConcave() = bounds.isConcave()
    override fun contains(point: Point) = bounds.contains(point)
    override fun methodWithALotOfParameters(x: Int, y: String, z: Boolean) = bounds.methodWithALotOfParameters(x, y, z)
    override fun color() = bounds.color()
    // and so on...
}

You can also imagine how horrible this would get, if the delegate isn't as short as bounds, but something like bounds.someProperty.anotherProperty.

The by syntax eliminates all that tedious work, letting you just write:

class Window(private val bounds: ClosedShape) : ClosedShape by bounds

And that's it! You can now use any Window as a ClosedShape.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1