Idea is to add new class modificator (“basic” for example) for classes with only one constructor argument, and use argument type and functions of this type by default when access values of this type.
basic class User(val name:String){
var isAlive = true
init {
if(name == "") throw IllegalArgumentException("Need name")
}
public fun kill(){
isAlive = false
}
}
val user:User = "John" // user.name="John" using "name" by default
println(user) // out "John" using "name" by default
println(user.length) // out "4" using "name" by default
user.kill() // isAlive = false using function of class User
Main goal is some type of extending of basic classes.
Adding transformation rules
basic class UpperCaseString(value:String){
var value:String = value
get() = value.toUpperCase()
}
var string:UpperCaseString = "Hello World"
print(string) // HELLO WORLD
Adding constraints
basic class PositiveInt(var value:Int){
init {
checkConstraints()
}
private fun checkConstraints(){
if(value<0) throw IllegalArgumentException("Must be positive Int")
}
operator fun plus(increment: Int): Int {
value = value + increment
checkConstraints()
}
.....
}
Adding functions without polluting of base class
basic class Note(var note:String){
private val SHARP = "♯"
private val FLAT = "♭"
public fun sharp(){
note = SHARP + note.last()
}
public fun flat(){
note = FLAT + note.last()
}
}
Are you familiar with Kotlin’s extension functions and delegated properties? Delegated properties allow you to solve item 2, and extension functions allow you to solve item 3. As for item 1, this doesn’t sound convincing (why don’t just perform the transformation in the constructor?)
var a:PositiveInt = 10
a += 10 //It is simple Int variable, but with restriction
Extension functions affect whole base class, that is not good idea. For example I need calculate different hashes from Login and Password classes, both of those is simple containers for only one String property.
In constructor I can make transformation only while construction phase. Whatever I will need use complex syntax for accessing only one String property.
var a = UpperCaseString("Hello World")
a.value += "!"
print(a.value)
VS
var a:UpperCaseString = "Hello World"
a += "!"
print(a)