Kotlin abstract class with generic param and methods which use type param

Viewed 12842

I'm trying to create an abstract class with generic parameter which will have subclasses which should call methods without having to specify type parameters. I have this so far:

abstract class AbstractClass<T : Any> @Autowired constructor(protected val delegate: MyService) {
    inline fun <T: Any> myMethod(param: Any): T? {
        return delegate.myMethod(param).`as`(T::class.java)
    }
}

And implementation:

class TesterWork @Autowired constructor(delegate: MyService) : AbstractClass<Tester>(delegate) {
}

Now when calling myMethod I have to specify the type argument:

testerWork.myMethod<Tester>("test")

I was wondering would it be possible to infer the type argument automatically? Can I somehow rework myMethod? Note that I need to have T::class.java inside the method.

4 Answers

Thanks to Fabian Zeindly I wrote a variant for several extended classes. In this case all of them should be declared in a title of an abstract class.

abstract class AbstractAdapter<V: AbstractAdapter.ViewHolder, I: AbstractAdapter.Item> : RecyclerView.Adapter<V>() {

    var list: List<I> = emptyList()

    override fun getItemCount(): Int = list.size

    open fun setItems(list: List<I>) {
        this.list = list.toMutableList()
    }

    open class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    open class Item
}

Then extend the class with new inner classes (ViewHolder, Item).

class NewAdapter(private var listener: View.OnClickListener?) : AbstractAdapter<NewAdapter.ViewHolder, NewAdapter.Item>() {

    private var originalItems: List<Item> = emptyList()

    override fun setItems(list: List<Item>) {
        super.setItems(list)
        this.originalItems = list.toMutableList()
        this.list = list.toMutableList()
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
        val view = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.layout, viewGroup, false)

        return ViewHolder(view)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
        val item = list[i]
        viewHolder.textView.text = item.text
        viewHolder.textView.tag = item.id
    }

    class ViewHolder(itemView: View) : AbstractAdapter.ViewHolder(itemView) {
        val textView: TextView = itemView.name
    }

    class Item(val id: Int, val text: String) : AbstractAdapter.Item()
}
Related