Everything else is just a tool to model your domain in a way that’s easier to read and reason about, and to produce much shorter code. Interfaces define module boundaries and can be mocked to enable simpler testing. Through classes, objects, and data structures, you can model your domain entities. Enums make a list of limited options crystal clear. Extensions allow you to add functionality to existing types, without having access to their original source code, giving advantage of better logic structure. With generics, you can write universal code, promoting reuse. And overloaded operators give that extra edge to common operations that benefit from succinct, crisp syntax.
Interfaces
Description of API that you can call.
Interfaces
An interface can describe methods (functions) and properties. It can also provide default implementations.
interface EquatableByID {
fun equalsByID(other: EquatableByID): Boolean
fun notEqualsByID(other: EquatableByID) = !equalsByID(other)
}
typealias ID = Int
interface Identifiable {
val id: ID
val idAsString: String
get() = "$id"
}
Interfaces can inherit from multiple interfaces.
interface IdentifiableEquatable: Identifiable, EquatableByID {
override fun equalsByID(other: EquatableByID): Boolean {
return if (other is Identifiable)
this.id == other.id
else
false
}
}
Classes and objects can implement multiple hierarchies of interfaces.
interface AnotherOne {
fun doSomething() {}
}
class Entity: IdentifiableEquatable, AnotherOne {
override val id = 1
}
Overriding implementations can call parent implementations.
fun logUsage() {
TODO()
}
class CustomizedEntity: IdentifiableEquatable {
override val id = 2
override fun notEqualsByID(other: EquatableByID): Boolean {
logUsage()
return super.notEqualsByID(other)
}
}
Conflicting declarations from multiple parents must be resolved via an override. Qualified super<...> reference can be used to refer to a specific parent implementation.
interface Conflicted {
fun equalsByID(other: EquatableByID): Boolean
}
class Resolved: IdentifiableEquatable, Conflicted {
override val id = 3
override fun equalsByID(other: EquatableByID): Boolean =
super<IdentifiableEquatable>.equalsByID(other)
}