I would like to use a default value for a function parameter in a class implementing an interface, like this:
interface FileStoreService {
fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true)
}
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean /* ?? */) {
// ....
}
}
Now here is what compiles and here is what doesn't compile:
KO : An overriding function is not allowed to specify default values for its parameters
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true) {
// ....
}
}
KO : Class 'LocalFileStoreService' is not abstract and does not implement abstract member public abstract fun storeFile(path: String, payload: InputStream, type: MediaType): Unit defined in fqn...FileStoreService
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
// ....
}
}
OK :
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType) {
storeFile(path, payload, type, true)
}
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
// ....
}
}
Is this the expected behaviour? Is there a better way to manage default parameter values in interfaces?
What you describe is odd, because by trying to reproduce it with Kotlin 1.4.20, I do not see the same behaviour.
Below code is working fine:
interface Test {
fun test(p1: String, p2: Boolean = true)
}
class TestImpl : Test {
// below commented function breaks compilation
//override fun test(p1: String) = println("That's odd... received: $p1")
// You cannot overwrite default value, that would break interface contract
override fun test(p1: String, p2: Boolean) = println("It works ! Received: $p1 and $p2")
}
fun main() {
// Default value for second parameter is deduced from interface signature
TestImpl().test("Hello")
}
If I uncomment the function without boolean parameter, compilation crashes, because the method does not inherit from the interface.
Generally speaking, if you define default values at interface level, it would be a bad idea to change the default value for a specific implementation, because it would break API contract.
Edit
Note that removing override keyword from commented function would produce valid code, because it becomes a function specific to the implementation. I find such behavior dangerous, though, because the following program:
interface Test {
fun test(p1: String, p2: Boolean = true)
}
class TestImpl : Test {
fun test(p1: String) = println("That's odd... received: $p1")
override fun test(p1: String, p2: Boolean) = println("It works ! Received: $p1 and $p2")
}
fun main() {
val t : Test = TestImpl()
t.test("Hello")
(t as TestImpl).test("Hello")
}
will then produce this output:
It works ! Received: Hello and true
That's odd... received: Hello
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.