Reputation: 2402
I have the following code in Dart programming language
class HttpResponse {
final int code;
final String? error;
HttpResponse.ok() : code = 200; <== This functionality
HttpResponse.notFound() <== This functionality
: code = 404,
error = 'Not found';
String toString() {
if (code == 200) return 'OK';
return 'ERROR $code ${error.toUpperCase()}';
}
}
How can I achieve this in Kotlin, I know that I can use static methods, however static methods don't have the purpose of initializing a class, is there a way where this can be achieved in Kotlin?
Upvotes: 6
Views: 4018
Reputation: 7499
I agree that sealed class
is the preferred way but there is another option of making the constructor private and accessing it via factory methods in companion object
. That way you can achieve "named constructors".
data class HttpResponse private constructor(
private val code: Int,
private val error: String? = null,
) {
companion object {
fun ok() = HttpResponse(200)
fun notFound() = HttpResponse(404, "Not found")
}
}
fun main() {
val responseOk = HttpResponse.ok()
val responseNotFound = HttpResponse.notFound()
}
Upvotes: 3
Reputation: 61
Sealed Classes is the way to go:
import java.util.Locale.US
sealed class HttpResponse(val code: Int, val error: String?) {
object Ok : HttpResponse(200, null)
object NotFound : HttpResponse(404, "Not found")
override fun toString() = when (this) {
Ok -> "OK"
NotFound -> "ERROR $code ${error?.uppercase(US)}"
}
}
fun main() {
println(HttpResponse.Ok) // OK
println(HttpResponse.NotFound) // ERROR 404 NOT FOUND
}
Since I cannot suggest an edit or post a comment, I am adding my modified version of zOqvxf's answer here.
If you keep your superclass parameters unexposed in this way, there is no worry for usage like HttpResponse.Ok(404)
as mentioned in the comment.
Upvotes: 2
Reputation: 1579
You're looking for Sealed Classes.
sealed class HttpResponse(val code: Int, val error: String? = null) {
class Ok(code: Int) : HttpResponse(code)
class NotFound(code: Int, error: String?) : HttpResponse(code, error)
override fun toString(): String {
return if (code == 200) "OK"
else "ERROR $code ${error?.toUpperCase()}"
}
}
fun main() {
val okResponse = HttpResponse.Ok(200)
val notFoundResponse = HttpResponse.NotFound(404, "Not found")
}
Upvotes: 9