Last active
November 20, 2016 14:28
-
-
Save brianyu0717/3a31947dacf9c180610886394d038282 to your computer and use it in GitHub Desktop.
Kotlin generics, inheritence and interfaces example showing multiple interface implementation, inheritance and co-/contra-variance in generics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| interface MustImplementAdd { | |
| fun theAddLol() : Int | |
| } | |
| interface MustImplementDivide { | |
| fun divide(a: Float, b: Float) : Float | |
| } | |
| abstract class Calculator(val name: String) { | |
| abstract fun calculate() : Double | |
| fun getMyName(): String = "my name is $name" | |
| } | |
| class BoxIn<in S : MustImplementAdd> { | |
| fun x(m : S) { | |
| m.theAddLol() | |
| } | |
| } | |
| class BoxOut<out S : MustImplementAdd>(val s : S) | |
| class BoxInAndOut<in T : MustImplementDivide, out S : MustImplementAdd>(val s : S) { | |
| fun x(t: T) { | |
| t.divide(1.2f, 2.0f) | |
| } | |
| } | |
| class AdditionAndDivisionCalculator(val a: Int, val b: Int, nameOfCalculator: String) : MustImplementAdd, MustImplementDivide, Calculator(nameOfCalculator) { | |
| override fun divide(a: Float, b: Float): Float { | |
| return a / b | |
| } | |
| override fun calculate(): Double { | |
| return a + b * 2.5 | |
| } | |
| override fun theAddLol(): Int { | |
| return a + b | |
| } | |
| } | |
| class DivisionCalculator() : MustImplementDivide { | |
| override fun divide(a: Float, b: Float): Float { | |
| return a / b | |
| } | |
| } | |
| class AdditionCalculator() : MustImplementAdd { | |
| override fun theAddLol(): Int { | |
| return 99 | |
| } | |
| } | |
| val additionCalculator = AdditionAndDivisionCalculator(1, 2, "Dr. Misty") | |
| val a = BoxIn<AdditionAndDivisionCalculator>() // BoxIn consumes some S that implements MustImplementAdd | |
| val b = a.x(additionCalculator) // we give into BoxIn some S that implements MustImplementAdd | |
| val c = BoxOut(additionCalculator).s // BoxOut produces some S that implements MustImplementAdd (Type of c is inferred to BoxOut<AdditionAndDivisionCalculator>) | |
| val d = c.getMyName() // we can get out some S that implements MustImplementAdd | |
| val e = BoxInAndOut<DivisionCalculator, AdditionCalculator>(AdditionCalculator()) | |
| val g = e.x(DivisionCalculator()) // put in an S, that implements MustImplementDivide | |
| val f = e.s // gets out an S, that implements MustImplementAdd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment