Reputation: 5984
Let's say I have an interface Base
and that we implement that interface in class Base1 : Base
.
I would expect an extension function in the form
fun ArrayList<Base>.myFun()
to also work on arrayListOf(Base1(), Base1()).myFun()
, but it doesn't. It requires the list to be of type Base
instead of Base1
.
Isn't this really strange? Or am I just missing something?
And, what are my options to write a function available on all subclasses of an interface?
Thanks!
Upvotes: 12
Views: 14311
Reputation: 13327
Lets say that you have:
interface Base
class Base1: Base
class Base2: Base
To have a fun for each class that extends your interface, you should create a class with a generic extension:
fun <T : Base> ArrayList<T>.myFun() = arrayListOf<T>()
In this case what you are doing is do an extension on any ArrayList
which container class would be any class that extends from your Base
interface. In the same way it will return an arraylist of that type.
In code this will look like:
fun myCode(){
val array1 : ArrayList<Base1> = arrayListOf(Base1()).myFun()
val array2 : ArrayList<Base2> = arrayListOf(Base2()).myFun()
}
You can read more about it in the official documentation, it has a lot of generic examples too: https://kotlinlang.org/docs/reference/extensions.html
Upvotes: 3
Reputation: 7472
You need to allow extension function to accept child implementation
interface Base
class Base1: Base
fun ArrayList<out Base>.myFun() = println(toString())
fun main(args: Array<String>) {
arrayListOf(Base1(), Base1()).myFun()
}
Upvotes: 12
Reputation: 271420
This:
fun ArrayList<Base>.myFun()
is an extension only on ArrayList<Base>
.
You can make the function generic to support any implementers of Base
:
fun <T : Base> ArrayList<T>.myFunc() {}
Usage:
ArrayList<Base1>().myFunc()
Upvotes: 0
Reputation: 2526
This should work with array list of any type:
fun <T> ArrayList<T>.myFun()
Upvotes: -1