Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: function delegation

I have a project that depends heavily on delegation and composition in Kotlin. Delegating properties is a breeze, but conceptually I'm not completely sure how to achieve delegation for functions in circumstances where the functions depend on other composed properties. I'd like to do something like this:

interface A {
  val a: String
}
class AImpl: A {
  override val a = "a"
}
interface B {
  val b: String
}
class BImpl: B {
  override val b = "b"
}

interface C<T> where T: A, T: B {
  fun c() : String
}

class CImpl<T>(val ab: T) : C<T> where T: A, T: B {
  override fun c() = ab.a + ab.b
}

// works
class ABC : A by AImpl(), B by BImpl()

// does not work
class ABC : A by AImpl(), B by BImpl(), C<ABC> by CImpl(this)

Of course, this type of thing would be achievable with the following:

interface A {
  val a: String
}
class AImpl: A {
  override val a = "a"
}
interface B {
  val b: String
}
class BImpl: B {
  override val b = "b"
}

interface C<T> where T: A, T: B {
  fun c() : String
}

class CImpl<T>(val ab: T) : C<T> where T: A, T: B {
  override fun c() = ab.a + ab.b
}

class AB : A by AImpl(), B by BImpl()

class ABC(ab: AB = AB(), c: C<AB> = CImpl<AB>(ab)) : A by ab, B by ab, C<AB> by c

but this feels clunky as it requires passing in objects for composition which bloats the size of the constructors - it would be cleaner for me to initialize the objects at the site of the class itself as they have no use outside of the class. Is there an elegant way to this with delegation and/or extensions?

like image 526
mikesol Avatar asked Jun 25 '17 10:06

mikesol


People also ask

How do I create a delegate on Kotlin?

You can create delegates as anonymous objects without creating new classes, by using the interfaces ReadOnlyProperty and ReadWriteProperty from the Kotlin standard library. They provide the required methods: getValue() is declared in ReadOnlyProperty ; ReadWriteProperty extends it and adds setValue() .

Why we use delegates in Android?

A delegate is just a class that provides the value for a property and handles its changes. This allows us to move, or delegate, the getter-setter logic from the property itself to a separate class, letting us reuse this logic.

What are delegated properties?

Simply put, delegated properties are not backed by a class field and delegate getting and setting to another piece of code. This allows for delegated functionality to be abstracted out and shared between multiple similar properties – e.g. storing property values in a map instead of separate fields.

What is a class delegate?

Delegates are the library class in System namespace. These are the type-safe pointer of any method. Delegates are mainly used in implementing the call-back methods and events. Delegates can be chained together as two or more methods can be called on a single event.


1 Answers

You can make C extend A and B instead of passing to it a delegate. e.g.:

interface C : A, B {
    fun c(): String
}

abstract class CImpl() : C {
    abstract override val a: String
    abstract override val b: String
    override fun c(): String = a + b
}

class ABC : A by AImpl(), B by BImpl(), CImpl()

You can also do this with a default implementation in C without a CImpl:

interface C : A, B {
    fun c(): String = a + b
}

class ABC : A by AImpl(), B by BImpl(), C
like image 73
mfulton26 Avatar answered Oct 04 '22 22:10

mfulton26