Reputation: 3000
I am really new to Kotlin and mostly coded in Javascript but I'm looking to see if I can dynamically create types while maintaining the static analysis. This is what I'm looking to achieve.
class TestOne {
def one(){
print('function one');
}
}
class TestTwo {
def two() {
print('function two');
}
}
workItOut("TestOne").one() // prints "function one"
workItOut("TestTwo").two() // prints "function two"
The workItOut
function will take the string and create the class
fun workItOut(name: String) {
if(name.equals("TestOne"))
return TestOne()
else if(name.equals("TestTwo"))
return TestTwo()
return ""
}
Upvotes: 0
Views: 969
Reputation: 85946
The typesafe way to achieve what you want is:
interface DoSomething {
fun foo()
}
class TestOne : DoSomething {
override fun foo() {
println("function one")
}
}
class TestTwo : DoSomething {
override fun foo() {
println("function two")
}
}
fun workItOut(name: String): DoSomething {
return when (name) {
"TestOne" -> TestOne()
"TestTwo" -> TestTwo()
else -> throw IllegalStateException("Invalid type identifier $name")
}
}
workItOut("TestOne").foo()
workItOut("TestTwo").foo()
The non-typesafe (and evil, non-kotlin, non-static typed) way is to use an unsafe cast and tell the function what result you expect to have (you seem to know what to expect because you are calling one()
versus two()
):
class TestOne {
fun one() {
println("function one")
}
}
class TestTwo {
fun twpo {
println("function two")
}
}
@Suppress("UNCHECKED_CAST")
fun <T: Any> workItOut(name: String): T {
return when (name) {
"TestOne" -> TestOne() as T
"TestTwo" -> TestTwo() as T
else -> throw IllegalStateException("Invalid type identifier $name")
}
}
workItOut<TestOne>("TestOne").one()
workItOut<TestTwo>("TestTwo").two()
Upvotes: 3