Here's the answers to the
chapter 11 exercises.
Exercise: Family Tree
fun man(description: Man.() -> Unit): Man =
Man().apply(description)
fun woman(description: Woman.() -> Unit): Woman =
Woman().apply(description)
class Man: Person() {
var wife: Woman? = null
fun wife(description: Woman.() -> Unit): Woman =
woman(description).also { woman ->
wife = woman
woman.husband = this
}
override fun toString(): String =
toString("Man", "wife", wife?.name)
}
class Woman: Person() {
var husband: Man? = null
fun husband(description: Man.() -> Unit): Man =
man(description).also { man ->
husband = man
man.wife = this
}
override fun toString(): String =
toString("Woman", "husband", husband?.name)
}
sealed class Person() {
val name = Name()
var father:Man? = null
var mother:Woman? = null
val children = mutableListOf<Person>()
fun name(description: Name.() -> Unit): Name =
name.apply(description)
fun father(description: Man.() -> Unit): Man =
man(description).also { man ->
father = man
man.children.add(this)
}
fun mother(description: Woman.() -> Unit): Woman =
woman(description).also { woman ->
mother = woman
woman.children.add(this)
}
fun son(description: Man.() -> Unit): Man =
man(description).also { man ->
children.add(man)
man.addParent(this)
}
fun daughter(description: Woman.() -> Unit): Woman =
woman(description).also { woman ->
children.add(woman)
woman.addParent(this)
}
protected fun addParent(parent: Person) {
when (parent) {
is Man -> {
father = parent
parent.wife?.let { mother ->
this.mother = mother
mother.children.add(this)
}
}
is Woman -> {
mother = parent
parent.husband?.let { father ->
this.father = father
father.children.add(this)
}
}
}
}
protected fun toString(
typeName: String,
spouseTypeName: String,
spouseName: Name?
): String =
"$typeName(" +
"name=$name, " +
"father=${father?.name}, " +
"mother=${mother?.name}, " +
"$spouseTypeName=$spouseName, " +
"children=${children.map {it.name}}" +
")"
}
data class Name(var first:String="",
var middle:String="",
var last:String="")