Regenerated samples
This commit is contained in:
parent
0c90f9a3e8
commit
61d375c927
|
@ -1,5 +1,5 @@
|
|||
// BuildingMaps/AssociateBy.kt
|
||||
import buildingmaps.*
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// BuildingMaps/AssociateByUnique.kt
|
||||
import buildingmaps.*
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// BuildingMaps/AssociateWith.kt
|
||||
import buildingmaps.*
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// BuildingMaps/ColorBlend.kt
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
import buildmaps.Color.*
|
||||
|
||||
fun blend(a: Color, b: Color): Color = when {
|
||||
a == b -> a
|
||||
a == Brown || b == Brown -> Brown
|
||||
else -> when (a to b) {
|
||||
Red to Blue, Blue to Red -> Purple
|
||||
Red to Yellow, Yellow to Red -> Orange
|
||||
Blue to Yellow, Yellow to Blue -> Green
|
||||
else -> {
|
||||
// Interesting but not accurate:
|
||||
val values = values()
|
||||
values[
|
||||
(a.ordinal + b.ordinal) % values.size]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun colorBlendTest(
|
||||
mix: (a: Color, b: Color) -> Color
|
||||
) {
|
||||
mix(Red, Red) eq Red
|
||||
mix(Purple, Brown) eq Brown
|
||||
mix(Red, Yellow) eq Orange
|
||||
mix(Yellow, Blue) eq Green
|
||||
mix(Purple, Orange) eq Blue // Not accurate
|
||||
}
|
||||
|
||||
fun main() {
|
||||
colorBlendTest(::blend)
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// BuildingMaps/FilterMap.kt
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// BuildingMaps/GetOrPut.kt
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// BuildingMaps/GroupBy.kt
|
||||
import buildingmaps.*
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// BuildingMaps/GroupByVsFilter.kt
|
||||
import buildingmaps.*
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// BuildingMaps/ImmutableBlendMap.kt
|
||||
@file:OptIn(ExperimentalStdlibApi::class)
|
||||
package buildmaps
|
||||
|
||||
class BlendMap {
|
||||
val map: Map<Pair<Color, Color>, Color> =
|
||||
buildMap {
|
||||
for (a in Color.values()) {
|
||||
for (b in Color.values()) {
|
||||
this[a to b] = buildmaps.blend(a, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
fun blend(a: Color, b: Color): Color =
|
||||
map.getOrDefault(a to b, Color.Brown)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
colorBlendTest(BlendMap()::blend)
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// BuildingMaps/PaintColors.kt
|
||||
package buildmaps
|
||||
|
||||
enum class Color {
|
||||
Red, Blue, Yellow, Purple,
|
||||
Green, Orange, Brown
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// BuildingMaps/People.kt
|
||||
package buildingmaps
|
||||
package buildmaps
|
||||
|
||||
data class Person(
|
||||
val name: String,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// BuildingMaps/SimilarOperation.kt
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// BuildingMaps/TransformingMap.kt
|
||||
package buildmaps
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -20,3 +20,9 @@ files:
|
|||
visible: true
|
||||
- name: src/SimilarOperation.kt
|
||||
visible: true
|
||||
- name: src/PaintColors.kt
|
||||
visible: true
|
||||
- name: src/ColorBlend.kt
|
||||
visible: true
|
||||
- name: src/ImmutableBlendMap.kt
|
||||
visible: true
|
||||
|
|
|
@ -8,4 +8,4 @@ Note the generic types `R?` (in `(Int, T) -> R?`) and `List<R>`. The `?` in
|
|||
`R?` means the lambda's return type is nullable. `mapIndexedNotNull()` returns
|
||||
a list of non-nullable elements, so the function return type is `List<R>`. To
|
||||
express that `R` is a non-nullable type, we specify a *constraint* on the
|
||||
generic type parameter: `R : Any`.
|
||||
generic type parameter: `R: Any`.
|
|
@ -1,5 +1,5 @@
|
|||
// LocalFunctions/ReturningFunc.kt
|
||||
package lambdawithreceiver
|
||||
package localfunctions
|
||||
import atomictest.eq
|
||||
|
||||
fun first(): (Int) -> Int {
|
||||
|
|
|
@ -27,14 +27,13 @@ val deck: List<Card> =
|
|||
|
||||
fun main() {
|
||||
val rand = Random(26)
|
||||
val trace = Trace()
|
||||
repeat(7) {
|
||||
trace("'${deck.random(rand)}'")
|
||||
}
|
||||
trace eq """
|
||||
'Jack of Hearts' 'Four of Hearts'
|
||||
'Five of Clubs' 'Seven of Clubs'
|
||||
'Jack of Diamonds' 'Ten of Spades'
|
||||
'Seven of Spades'
|
||||
'Jack of Hearts' 'Four of Hearts'
|
||||
'Five of Clubs' 'Seven of Clubs'
|
||||
'Jack of Diamonds' 'Ten of Spades'
|
||||
'Seven of Spades'
|
||||
"""
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// MemberReferences/ExtensionReference.kt
|
||||
package memberreferences
|
||||
import atomictest.eq
|
||||
|
||||
fun Int.times47() = times(47)
|
||||
|
||||
class Frog
|
||||
fun Frog.speak() = "Ribbit!"
|
||||
|
||||
fun goInt(n: Int, g: (Int) -> Int) = g(n)
|
||||
|
||||
fun goFrog(frog: Frog, g: (Frog) -> String) =
|
||||
g(frog)
|
||||
|
||||
fun main() {
|
||||
goInt(12, Int::times47) eq 564
|
||||
goFrog(Frog(), Frog::speak) eq "Ribbit!"
|
||||
}
|
|
@ -10,3 +10,5 @@ files:
|
|||
visible: true
|
||||
- name: src/ConstructorReference.kt
|
||||
visible: true
|
||||
- name: src/ExtensionReference.kt
|
||||
visible: true
|
||||
|
|
|
@ -1,52 +1,51 @@
|
|||
// Sequences/EagerVsLazyEvaluation.kt
|
||||
package creatingsequences
|
||||
import atomictest.*
|
||||
|
||||
fun Int.isEven(): Boolean {
|
||||
println("$this.isEven()")
|
||||
trace("$this.isEven()")
|
||||
return this % 2 == 0
|
||||
}
|
||||
|
||||
fun Int.square(): Int {
|
||||
println("$this.square()")
|
||||
trace("$this.square()")
|
||||
return this * this
|
||||
}
|
||||
|
||||
fun Int.lessThanTen(): Boolean {
|
||||
println("${this}.lessThanTen()")
|
||||
trace("${this}.lessThanTen()")
|
||||
return this < 10
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val list = listOf(1, 2, 3, 4)
|
||||
|
||||
println(">>> List:")
|
||||
val r1 = list
|
||||
trace(">>> List:")
|
||||
trace(list
|
||||
.filter(Int::isEven)
|
||||
.map(Int::square)
|
||||
.any(Int::lessThanTen)
|
||||
println(r1)
|
||||
.any(Int::lessThanTen))
|
||||
|
||||
println(">>> Sequence:")
|
||||
val r2 = list.asSequence()
|
||||
trace(">>> Sequence:")
|
||||
trace(list.asSequence()
|
||||
.filter(Int::isEven)
|
||||
.map(Int::square)
|
||||
.any(Int::lessThanTen)
|
||||
println(r2)
|
||||
}
|
||||
/* Output:
|
||||
>>> List:
|
||||
1.isEven()
|
||||
2.isEven()
|
||||
3.isEven()
|
||||
4.isEven()
|
||||
2.square()
|
||||
4.square()
|
||||
4.lessThanTen()
|
||||
true
|
||||
>>> Sequence:
|
||||
1.isEven()
|
||||
2.isEven()
|
||||
2.square()
|
||||
4.lessThanTen()
|
||||
true
|
||||
*/
|
||||
.any(Int::lessThanTen))
|
||||
trace eq """
|
||||
>>> List:
|
||||
1.isEven()
|
||||
2.isEven()
|
||||
3.isEven()
|
||||
4.isEven()
|
||||
2.square()
|
||||
4.square()
|
||||
4.lessThanTen()
|
||||
true
|
||||
>>> Sequence:
|
||||
1.isEven()
|
||||
2.isEven()
|
||||
2.square()
|
||||
4.lessThanTen()
|
||||
true
|
||||
"""
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
// Sequences/TerminalOperations.kt
|
||||
package creatingsequences
|
||||
import atomictest.*
|
||||
|
||||
fun main() {
|
||||
val list = listOf(1, 2, 3, 4)
|
||||
val r = list.asSequence()
|
||||
trace(list.asSequence()
|
||||
.filter(Int::isEven)
|
||||
.map(Int::square)
|
||||
.toList()
|
||||
println(r)
|
||||
}
|
||||
/* Output:
|
||||
1.isEven()
|
||||
2.isEven()
|
||||
2.square()
|
||||
3.isEven()
|
||||
4.isEven()
|
||||
4.square()
|
||||
[4, 16]
|
||||
*/
|
||||
.toList())
|
||||
trace eq """
|
||||
1.isEven()
|
||||
2.isEven()
|
||||
2.square()
|
||||
3.isEven()
|
||||
4.isEven()
|
||||
4.square()
|
||||
[4, 16]
|
||||
"""
|
||||
}
|
|
@ -1,15 +1,13 @@
|
|||
// Testing/Trace1.kt
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
fun main() {
|
||||
trace("line 1")
|
||||
trace(47)
|
||||
trace("line 2")
|
||||
trace eq """
|
||||
line 1
|
||||
47
|
||||
line 2
|
||||
line 1
|
||||
47
|
||||
line 2
|
||||
"""
|
||||
}
|
|
@ -10,11 +10,11 @@ interface Parent {
|
|||
|
||||
class Actual(
|
||||
override val ch: Char // [1]
|
||||
) : Parent {
|
||||
): Parent {
|
||||
override fun f() = 17 // [2]
|
||||
}
|
||||
|
||||
class Other : Parent {
|
||||
class Other: Parent {
|
||||
override val ch: Char // [3]
|
||||
get() = 'B'
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
package multipleinheritance2
|
||||
|
||||
interface Animal
|
||||
interface Mammal : Animal
|
||||
interface AquaticAnimal : Animal
|
||||
interface Mammal: Animal
|
||||
interface AquaticAnimal: Animal
|
||||
|
||||
class Dolphin : Mammal, AquaticAnimal
|
||||
class Dolphin: Mammal, AquaticAnimal
|
|
@ -2,8 +2,8 @@
|
|||
package multipleinheritance1
|
||||
|
||||
open class Animal
|
||||
open class Mammal : Animal()
|
||||
open class AquaticAnimal : Animal()
|
||||
open class Mammal: Animal()
|
||||
open class AquaticAnimal: Animal()
|
||||
|
||||
// More than one base class won't compile:
|
||||
// class Dolphin: Mammal(), AquaticAnimal()
|
|
@ -7,7 +7,7 @@ interface WithPropertyAccessor {
|
|||
get() = 11
|
||||
}
|
||||
|
||||
class Impl : WithPropertyAccessor
|
||||
class Impl: WithPropertyAccessor
|
||||
|
||||
fun main() {
|
||||
Impl().a eq 11
|
||||
|
|
|
@ -7,13 +7,13 @@ open class GreatApe(
|
|||
val age: Int
|
||||
)
|
||||
|
||||
open class Bonobo(weight: Double, age: Int) :
|
||||
open class Bonobo(weight: Double, age: Int):
|
||||
GreatApe(weight, age)
|
||||
|
||||
class Chimpanzee(weight: Double, age: Int) :
|
||||
class Chimpanzee(weight: Double, age: Int):
|
||||
GreatApe(weight, age)
|
||||
|
||||
class BonoboB(weight: Double, age: Int) :
|
||||
class BonoboB(weight: Double, age: Int):
|
||||
Bonobo(weight, age)
|
||||
|
||||
fun info(ape: GreatApe) =
|
||||
|
|
|
@ -23,7 +23,7 @@ class VacationHouse(
|
|||
zip: String,
|
||||
val startMonth: String,
|
||||
val endMonth: String
|
||||
) : House(address, state, zip) {
|
||||
): House(address, state, zip) {
|
||||
override fun toString() =
|
||||
"Vacation house at $fullAddress " +
|
||||
"from $startMonth to $endMonth"
|
||||
|
@ -31,7 +31,7 @@ class VacationHouse(
|
|||
|
||||
class TreeHouse(
|
||||
val name: String
|
||||
) : House("Tree Street, TR 00000") {
|
||||
): House("Tree Street, TR 00000") {
|
||||
override fun toString() =
|
||||
"$name tree house at $fullAddress"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// BaseClassInit/NoArgConstructor.kt
|
||||
|
||||
open class SuperClass1(val i: Int)
|
||||
class SubClass1(i: Int) : SuperClass1(i)
|
||||
class SubClass1(i: Int): SuperClass1(i)
|
||||
|
||||
open class SuperClass2
|
||||
class SubClass2 : SuperClass2()
|
||||
class SubClass2: SuperClass2()
|
|
@ -4,7 +4,7 @@ import atomictest.eq
|
|||
|
||||
open class Base(val i: Int)
|
||||
|
||||
class Derived : Base {
|
||||
class Derived: Base {
|
||||
constructor(i: Int) : super(i)
|
||||
constructor() : this(9)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import atomictest.eq
|
|||
class DelegatedControls(
|
||||
private val controls: SpaceShipControls =
|
||||
SpaceShipControls()
|
||||
) : ShipControls by controls {
|
||||
): ShipControls by controls {
|
||||
override fun turboBoost(): String =
|
||||
"${controls.turboBoost()}... boooooost!"
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
package classdelegation
|
||||
import atomictest.eq
|
||||
|
||||
class ExplicitControls : ShipControls {
|
||||
class ExplicitControls: ShipControls {
|
||||
private val controls = SpaceShipControls()
|
||||
// Delegated members:
|
||||
override fun up(velocity: Int) =
|
||||
|
|
|
@ -9,7 +9,7 @@ interface Rectangle {
|
|||
class ButtonImage(
|
||||
val width: Int,
|
||||
val height: Int
|
||||
) : Rectangle {
|
||||
): Rectangle {
|
||||
override fun paint() = width * height
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ interface MouseManager {
|
|||
fun hovering(): Boolean
|
||||
}
|
||||
|
||||
class UserInput : MouseManager {
|
||||
class UserInput: MouseManager {
|
||||
override fun clicked() = true
|
||||
override fun hovering() = true
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class Button(
|
|||
val image: Rectangle =
|
||||
ButtonImage(width, height),
|
||||
val input: MouseManager = UserInput()
|
||||
) : Rectangle by image, MouseManager by input
|
||||
): Rectangle by image, MouseManager by input
|
||||
|
||||
fun main() {
|
||||
val button = Button(10, 5)
|
||||
|
|
|
@ -11,7 +11,7 @@ interface ShipControls {
|
|||
fun turboBoost(): String
|
||||
}
|
||||
|
||||
class SpaceShipControls : ShipControls {
|
||||
class SpaceShipControls: ShipControls {
|
||||
override fun up(velocity: Int) =
|
||||
"up $velocity"
|
||||
override fun down(velocity: Int) =
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
## Class Delegation (#2)
|
||||
|
||||
Exercise 3 in [Inheritance & Extensions] uses composition to adapt `MyClass` to
|
||||
work with `UsefulLibrary`. This produces an inconsistency when using `MyClass`
|
||||
with the `useMyClass()` function: the composed `field` must be explicitly named
|
||||
during the call:
|
||||
Exercise 3 in [Inheritance & Extensions] uses
|
||||
composition to adapt `MyClass` to work with `UsefulLibrary`. This produces an
|
||||
inconsistency when using `MyClass` with the `useMyClass()` function: the
|
||||
composed `field` must be explicitly named during the call:
|
||||
|
||||
```kotlin
|
||||
useMyClass(mc.field)
|
||||
|
|
|
@ -22,5 +22,5 @@ interface B {
|
|||
Create a class `AA` that implements `A`, producing the value `1` for `x` and
|
||||
`z`, and tracing `"AA.u()"` for `u()` and `"AA.v()"` for `v()`. Create a
|
||||
similar implementation `BB` implementing `B`. Now create a class `Delegation`
|
||||
which delegates to both `A` and `B`. IntelliJ or the compiler will tell you
|
||||
what you need to do to solve the collisions.
|
||||
which delegates to both `A` and `B`. IntelliJ or the compiler will guide you in
|
||||
resolving the collisions.
|
|
@ -2,9 +2,7 @@
|
|||
package companionobjects
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
class ZIClosed : ZI {
|
||||
class ZIClosed: ZI {
|
||||
override fun f() = "ZIClosed.f()"
|
||||
override fun g() = "ZIClosed.g()"
|
||||
}
|
||||
|
@ -36,5 +34,5 @@ fun main() {
|
|||
ZIClosed.f()
|
||||
ZIDelegationInheritance.g()
|
||||
ZIDelegationInheritance.h()
|
||||
"""
|
||||
"""
|
||||
}
|
|
@ -2,14 +2,12 @@
|
|||
package companionobjects
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
interface ZI {
|
||||
fun f(): String
|
||||
fun g(): String
|
||||
}
|
||||
|
||||
open class ZIOpen : ZI {
|
||||
open class ZIOpen: ZI {
|
||||
override fun f() = "ZIOpen.f()"
|
||||
override fun g() = "ZIOpen.g()"
|
||||
}
|
||||
|
@ -52,5 +50,5 @@ fun main() {
|
|||
ZIOpen.f()
|
||||
ZICompanionInheritance.g()
|
||||
ZICompanionInheritance.h()
|
||||
"""
|
||||
"""
|
||||
}
|
|
@ -9,9 +9,12 @@ class WithCompanion {
|
|||
fun g() = i + f()
|
||||
}
|
||||
|
||||
fun WithCompanion.Companion.h() = f() * i
|
||||
|
||||
fun main() {
|
||||
WithCompanion.i eq 3
|
||||
WithCompanion.f() eq 9
|
||||
val wc = WithCompanion()
|
||||
wc.g() eq 12
|
||||
WithCompanion.i eq 3
|
||||
WithCompanion.f() eq 9
|
||||
WithCompanion.h() eq 27
|
||||
}
|
|
@ -2,11 +2,11 @@
|
|||
package companionobjects
|
||||
import atomictest.eq
|
||||
|
||||
interface Extended : ZI {
|
||||
interface Extended: ZI {
|
||||
fun u(): String
|
||||
}
|
||||
|
||||
class Extend : ZI by Companion, Extended {
|
||||
class Extend: ZI by Companion, Extended {
|
||||
companion object: ZI {
|
||||
override fun f() = "Extend.f()"
|
||||
override fun g() = "Extend.g()"
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
package companionobjects
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
class CompanionInit {
|
||||
companion object {
|
||||
init {
|
||||
|
@ -21,10 +19,10 @@ fun main() {
|
|||
CompanionInit()
|
||||
trace("After 3")
|
||||
trace eq """
|
||||
Before
|
||||
Companion Constructor
|
||||
After 1
|
||||
After 2
|
||||
After 3
|
||||
Before
|
||||
Companion Constructor
|
||||
After 1
|
||||
After 2
|
||||
After 3
|
||||
"""
|
||||
}
|
|
@ -18,8 +18,8 @@ interface VendorFactory {
|
|||
```
|
||||
|
||||
Create `Vendor1` and `Vendor2` which implement `Vendor`. The member functions
|
||||
use `Trace` to report the `Vendor` class name and "pencil" or "pen". Each
|
||||
`Vendor` implementation also has a `companion object` with a `factory` property
|
||||
use `trace()` to report the `Vendor` class name and "pencil" or "pen". Each
|
||||
`Vendor` implementation also has a companion object with a `factory` property
|
||||
containing an anonymous inner class that implements `VendorFactory`.
|
||||
|
||||
Now write a standalone function `consumer(factory: VendorFactory)` which uses
|
||||
|
|
|
@ -17,10 +17,10 @@ interface GameFactory {
|
|||
}
|
||||
```
|
||||
|
||||
Create two classes, `Checkers` and `Chess` which inherit `BoardGame`. Give them
|
||||
both `private` constructors with no arguments. Each class should contain a
|
||||
`companion object Factory : GameFactory` which calls `createBoard()` in its
|
||||
constructor. Each `companion object` contains a `const val max` which is used
|
||||
Create two classes, `Checkers` and `Chess`, which inherit `BoardGame`. Give
|
||||
them both `private` constructors with no arguments. Each class should contain a
|
||||
`companion object Factory: GameFactory` which calls `createBoard()` in its
|
||||
constructor. Each companion object contains a `const val max` which is used
|
||||
within `move()`. The definitions of `playGame()` and `main()` are provided;
|
||||
complete the code in `Checkers` and `Chess` so it satisfies the tests in
|
||||
`main()`.
|
|
@ -17,7 +17,7 @@ data class ID(
|
|||
}
|
||||
```
|
||||
|
||||
`ID` only contains a `companion object` with `idGenerator()` and the code to
|
||||
`ID` only contains a companion object with `idGenerator()` and the code to
|
||||
support that function: the `size` of each `id`, a random-number generator
|
||||
seeded to the value of `47`, and a `source` of the characters used to randomly
|
||||
create the `id`. In `main()`, the output is checked using `test()`, which
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
package composition
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
class Engine {
|
||||
fun start() = trace("Engine start")
|
||||
fun stop() = trace("Engine stop")
|
||||
|
|
|
@ -4,6 +4,6 @@ package composition1
|
|||
interface Building
|
||||
interface Kitchen
|
||||
|
||||
interface House : Building {
|
||||
interface House: Building {
|
||||
val kitchen: Kitchen
|
||||
}
|
|
@ -4,7 +4,7 @@ package composition2
|
|||
interface Building
|
||||
interface Kitchen
|
||||
|
||||
interface House : Building {
|
||||
interface House: Building {
|
||||
val kitchen1: Kitchen
|
||||
val kitchen2: Kitchen
|
||||
}
|
|
@ -4,6 +4,6 @@ package composition3
|
|||
interface Building
|
||||
interface Kitchen
|
||||
|
||||
interface House : Building {
|
||||
interface House: Building {
|
||||
val kitchens: List<Kitchen>
|
||||
}
|
|
@ -4,15 +4,15 @@ import atomictest.eq
|
|||
|
||||
interface Creature
|
||||
|
||||
class Human : Creature {
|
||||
class Human: Creature {
|
||||
fun greeting() = "I'm Human"
|
||||
}
|
||||
|
||||
class Dog : Creature {
|
||||
class Dog: Creature {
|
||||
fun bark() = "Yip!"
|
||||
}
|
||||
|
||||
class Alien : Creature {
|
||||
class Alien: Creature {
|
||||
fun mobility() = "Three legs"
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ interface Base {
|
|||
fun f()
|
||||
}
|
||||
|
||||
class Derived1 : Base {
|
||||
class Derived1: Base {
|
||||
override fun f() {}
|
||||
fun g() {}
|
||||
}
|
||||
|
||||
class Derived2 : Base {
|
||||
class Derived2: Base {
|
||||
override fun f() {}
|
||||
fun h() {}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ package inheritanceextensions
|
|||
import usefullibrary.*
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
open class MyClass {
|
||||
fun g() = trace("g()")
|
||||
fun h() = trace("h()")
|
||||
|
@ -15,7 +13,7 @@ fun useMyClass(mc: MyClass) {
|
|||
mc.h()
|
||||
}
|
||||
|
||||
class MyClassAdaptedForLib :
|
||||
class MyClassAdaptedForLib:
|
||||
MyClass(), LibType {
|
||||
override fun f1() = h()
|
||||
override fun f2() = g()
|
||||
|
@ -27,11 +25,11 @@ fun main() {
|
|||
utility2(mc)
|
||||
useMyClass(mc)
|
||||
trace eq """
|
||||
h()
|
||||
g()
|
||||
g()
|
||||
h()
|
||||
g()
|
||||
h()
|
||||
h()
|
||||
g()
|
||||
g()
|
||||
h()
|
||||
g()
|
||||
h()
|
||||
"""
|
||||
}
|
|
@ -3,8 +3,6 @@ package inheritanceextensions2
|
|||
import usefullibrary.*
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
class MyClass { // Not open
|
||||
fun g() = trace("g()")
|
||||
fun h() = trace("h()")
|
||||
|
@ -15,7 +13,7 @@ fun useMyClass(mc: MyClass) {
|
|||
mc.h()
|
||||
}
|
||||
|
||||
class MyClassAdaptedForLib : LibType {
|
||||
class MyClassAdaptedForLib: LibType {
|
||||
val field = MyClass()
|
||||
override fun f1() = field.h()
|
||||
override fun f2() = field.g()
|
||||
|
@ -27,11 +25,11 @@ fun main() {
|
|||
utility2(mc)
|
||||
useMyClass(mc.field)
|
||||
trace eq """
|
||||
h()
|
||||
g()
|
||||
g()
|
||||
h()
|
||||
g()
|
||||
h()
|
||||
h()
|
||||
g()
|
||||
g()
|
||||
h()
|
||||
g()
|
||||
h()
|
||||
"""
|
||||
}
|
|
@ -16,7 +16,7 @@ fun Device.outdated() =
|
|||
class MyDevice(
|
||||
override val model: String,
|
||||
override val productionYear: Int
|
||||
) : Device
|
||||
): Device
|
||||
|
||||
fun main() {
|
||||
val gadget: Device =
|
||||
|
|
|
@ -12,7 +12,7 @@ interface Device {
|
|||
class MyDevice(
|
||||
override val model: String,
|
||||
override val productionYear: Int
|
||||
) : Device
|
||||
): Device
|
||||
|
||||
fun main() {
|
||||
val gadget: Device =
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
package inheritanceextensions
|
||||
import atomictest.eq
|
||||
|
||||
class HVAC : Heater() {
|
||||
class HVAC: Heater() {
|
||||
fun cool(temperature: Int) =
|
||||
"cooling to $temperature"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// InheritanceExtensions/NoExtOverride.kt
|
||||
package inheritanceextensions
|
||||
import atomictest.*
|
||||
|
||||
open class Base {
|
||||
open fun f() = "Base.f()"
|
||||
}
|
||||
|
||||
class Derived: Base() {
|
||||
override fun f() = "Derived.f()"
|
||||
}
|
||||
|
||||
fun Base.g() = "Base.g()"
|
||||
fun Derived.g() = "Derived.g()"
|
||||
|
||||
fun useBase(b: Base) {
|
||||
trace("Received ${b::class.simpleName}")
|
||||
trace(b.f())
|
||||
trace(b.g())
|
||||
}
|
||||
|
||||
fun main() {
|
||||
useBase(Base())
|
||||
useBase(Derived())
|
||||
trace eq """
|
||||
Received Base
|
||||
Base.f()
|
||||
Base.g()
|
||||
Received Derived
|
||||
Derived.f()
|
||||
Base.g()
|
||||
"""
|
||||
}
|
|
@ -2,8 +2,6 @@
|
|||
package inheritanceextensions
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
class TemperatureDelta(
|
||||
val current: Double,
|
||||
val target: Double
|
||||
|
@ -28,7 +26,7 @@ fun main() {
|
|||
adjust(TemperatureDelta(60.0, 70.0))
|
||||
adjust(TemperatureDelta(80.0, 60.0))
|
||||
trace eq """
|
||||
heating to 70.0
|
||||
cooling to 60.0
|
||||
heating to 70.0
|
||||
cooling to 60.0
|
||||
"""
|
||||
}
|
|
@ -18,6 +18,8 @@ files:
|
|||
visible: true
|
||||
- name: src/PrivateAccess.kt
|
||||
visible: true
|
||||
- name: src/NoExtOverride.kt
|
||||
visible: true
|
||||
- name: src/DeviceMembers.kt
|
||||
visible: true
|
||||
- name: src/DeviceExtensions.kt
|
||||
|
|
|
@ -4,6 +4,4 @@ Starting with `TemperatureDelta.kt`, add two extension functions `openWindow()`
|
|||
and `fan()` as cooling strategies. Add a class `TemperatureDelta2`, but use
|
||||
member functions instead of extension functions. Add an overloaded `adjust()`
|
||||
function that takes a `TemperatureDelta2`. Which approach is better, or do they
|
||||
seem about the same?
|
||||
|
||||
{{ Solution already exists but names need to be changed }}
|
||||
seem about the same?
|
|
@ -3,4 +3,4 @@ package inheritance
|
|||
|
||||
open class Base
|
||||
|
||||
class Derived : Base()
|
||||
class Derived: Base()
|
|
@ -7,9 +7,9 @@ open class GreatApe {
|
|||
val age = 12
|
||||
}
|
||||
|
||||
open class Bonobo : GreatApe()
|
||||
class Chimpanzee : GreatApe()
|
||||
class BonoboB : Bonobo()
|
||||
open class Bonobo: GreatApe()
|
||||
class Chimpanzee: GreatApe()
|
||||
class BonoboB: Bonobo()
|
||||
|
||||
fun info(ape: GreatApe) =
|
||||
"weight: ${ape.weight} age: ${ape.age}"
|
||||
|
|
|
@ -16,7 +16,7 @@ open class GreatApe {
|
|||
fun energyLevel() = "Energy: $energy"
|
||||
}
|
||||
|
||||
class Bonobo : GreatApe() {
|
||||
class Bonobo: GreatApe() {
|
||||
override fun call() = "Eep!"
|
||||
override fun eat() {
|
||||
// Modify the base-class var:
|
||||
|
@ -29,7 +29,7 @@ class Bonobo : GreatApe() {
|
|||
fun run() = "Bonobo run"
|
||||
}
|
||||
|
||||
class Chimpanzee : GreatApe() {
|
||||
class Chimpanzee: GreatApe() {
|
||||
// New property
|
||||
val additionalEnergy = 20
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ package inheritance
|
|||
// This class can be inherited:
|
||||
open class Parent
|
||||
|
||||
class Child : Parent()
|
||||
class Child: Parent()
|
||||
|
||||
// Child is not open, so this fails:
|
||||
// class GrandChild: Child()
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
package innerclasses
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
interface Counter {
|
||||
fun next(): Int
|
||||
}
|
||||
|
@ -12,7 +10,7 @@ class CounterFactory {
|
|||
private var count = 0
|
||||
fun new(name: String): Counter {
|
||||
// Local inner class:
|
||||
class Local : Counter {
|
||||
class Local: Counter {
|
||||
init { trace("Local()") }
|
||||
override fun next(): Int {
|
||||
// Access local identifiers:
|
||||
|
@ -24,7 +22,7 @@ class CounterFactory {
|
|||
}
|
||||
fun new2(name: String): Counter {
|
||||
// Instance of an anonymous inner class:
|
||||
return object : Counter {
|
||||
return object: Counter {
|
||||
init { trace("Counter()") }
|
||||
override fun next(): Int {
|
||||
// Access local identifiers:
|
||||
|
@ -45,5 +43,5 @@ fun main() {
|
|||
trace eq """
|
||||
Local() Local 0 Local 1 Local 2 Local 3
|
||||
Counter() Anon 4 Anon 5 Anon 6 Anon 7
|
||||
"""
|
||||
"""
|
||||
}
|
|
@ -8,7 +8,7 @@ class Hotel(private val reception: String) {
|
|||
fun callReception() =
|
||||
"Room $id Calling $reception"
|
||||
}
|
||||
private inner class Closet : Room()
|
||||
private inner class Closet: Room()
|
||||
fun closet(): Room = Closet()
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
package innerclasses
|
||||
import atomictest.*
|
||||
|
||||
private val trace = Trace()
|
||||
|
||||
open class Egg {
|
||||
private var yolk = Yolk()
|
||||
open inner class Yolk {
|
||||
|
@ -15,8 +13,8 @@ open class Egg {
|
|||
fun g() { yolk.f() }
|
||||
}
|
||||
|
||||
class BigEgg : Egg() {
|
||||
inner class Yolk : Egg.Yolk() {
|
||||
class BigEgg: Egg() {
|
||||
inner class Yolk: Egg.Yolk() {
|
||||
init { trace("BigEgg.Yolk()") }
|
||||
override fun f() {
|
||||
trace("BigEgg.Yolk.f()")
|
||||
|
@ -28,10 +26,10 @@ class BigEgg : Egg() {
|
|||
fun main() {
|
||||
BigEgg().g()
|
||||
trace eq """
|
||||
Egg.Yolk()
|
||||
New Egg()
|
||||
Egg.Yolk()
|
||||
BigEgg.Yolk()
|
||||
BigEgg.Yolk.f()
|
||||
Egg.Yolk()
|
||||
New Egg()
|
||||
Egg.Yolk()
|
||||
BigEgg.Yolk()
|
||||
BigEgg.Yolk.f()
|
||||
"""
|
||||
}
|
|
@ -11,7 +11,7 @@ class PetCreator {
|
|||
fun dog(): Pet {
|
||||
val say = "Bark"
|
||||
// Local inner class:
|
||||
class Dog : Pet {
|
||||
class Dog: Pet {
|
||||
override fun speak() = say + home()
|
||||
}
|
||||
return Dog()
|
||||
|
@ -19,7 +19,7 @@ class PetCreator {
|
|||
fun cat(): Pet {
|
||||
val emit = "Meow"
|
||||
// Anonymous inner class:
|
||||
return object : Pet {
|
||||
return object: Pet {
|
||||
override fun speak() = emit + home()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ interface Selector<T> {
|
|||
returns the current element pointed to by the `Selector`, and `next()` moves
|
||||
to the next element in the `List`.
|
||||
|
||||
Define a standalone function `<T> traceAll(select: Selector<T>)` that creates a
|
||||
`Trace` object called `trace`, then uses `select` to append all the values of
|
||||
`current()` to `trace` using `+=`, then returns `trace`.
|
||||
Define a standalone function `<T> traceAll(select: Selector<T>)` that uses
|
||||
`select` to append all the values of `current()` to `trace` using `+=`, then
|
||||
returns `trace`.
|
||||
|
||||
Now make `Container` inherit from `Iterable<T>`, and add a function called
|
||||
`iterator()` that returns an instance of an anonymous inner class that inherits
|
||||
|
|