Manuel Pérez Alcolea
07/24/2020, 6:06 PMby exists.
So, my idea was to have, for example, something like this...Manuel Pérez Alcolea
07/24/2020, 6:07 PMstreetsofboston
07/24/2020, 6:08 PMHumanoid and interface as well.Manuel Pérez Alcolea
07/24/2020, 6:08 PMPerson classManuel Pérez Alcolea
07/24/2020, 6:08 PMManuel Pérez Alcolea
07/24/2020, 6:12 PMPerson.name, I need to give them a reference to that instance of Person. The issue is, I can only do so by sacrificing some null safety, because, for example, in the constructor for Person, talker and walker need a reference to the Person - which is not possible because it's still being created (it's the constructor, after all, and there's no this for Person yet)Manuel Pérez Alcolea
07/24/2020, 6:13 PMManuel Pérez Alcolea
07/24/2020, 6:14 PMManuel Pérez Alcolea
07/24/2020, 6:14 PMManuel Pérez Alcolea
07/24/2020, 6:15 PMManuel Pérez Alcolea
07/24/2020, 6:16 PMPerson just wrap the data, and give the implementations for the interfaces some constructors so it can be passed to them as wellManuel Pérez Alcolea
07/24/2020, 6:17 PMstreetsofboston
07/24/2020, 6:18 PMManuel Pérez Alcolea
07/24/2020, 6:18 PMby and setting all the methods myself and/or make the interfaces have nullable properties, so I can pass them the reference after building the PersonManuel Pérez Alcolea
07/24/2020, 6:18 PMManuel Pérez Alcolea
07/24/2020, 6:19 PMstreetsofboston
07/24/2020, 8:24 PMinterface Trait<M> {
var m: () -> M
}
interface CanMove {
fun move()
}
interface CanCommunicate {
fun communicate()
}
interface TraitCanMove : CanMove, Trait<Person> {
override fun move() {
println("Moving person ${m().name}")
}
}
interface TraitCanCommunicate : CanCommunicate, Trait<Person> {
override fun communicate() {
println("Talking to person ${m().name}")
}
}
class Person private constructor(
walker: TraitCanMove,
talker: TraitCanCommunicate,
val name: String
) : CanMove by walker, CanCommunicate by talker {
companion object {
operator fun invoke(
walker: TraitCanMove,
talker: TraitCanCommunicate,
name: String
): Person {
return { Person(walker, talker, name) }.prepareTraits(walker, talker)
}
}
}
fun <T> (() -> T).prepareTraits(vararg traits: Trait<T>): T {
traits.forEach { it.m = this }
return this()
}Manuel Pérez Alcolea
07/25/2020, 7:16 PMcompanion object works as a factory there, but TraitCanMove and TraitCanCommunicate are interfaces, which is what it asks for. So should I implement classes with them as base too, @streetsofboston?streetsofboston
07/25/2020, 7:28 PMstreetsofboston
07/25/2020, 7:30 PMManuel Pérez Alcolea
07/25/2020, 7:32 PMstreetsofboston
07/25/2020, 7:33 PMManuel Pérez Alcolea
07/25/2020, 7:33 PMManuel Pérez Alcolea
07/25/2020, 7:33 PMManuel Pérez Alcolea
07/25/2020, 7:34 PM