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 Person
Manuel 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