Search code examples
kotlininterfaceinterface-implementationclicklistener

Abstract fun invoke() not implemented


I've created a View and I encountered a problem with my interface for Buttons ClickListener. Interface looks like this

interface CustomButtonsClickListener : () -> Unit {
        fun onPlusClick(view: View, button: ImageButton)
        fun onMinusClick(view: View, button: ImageButton)
    }

It is implemented by the method:

fun setCustomButtonsClickListeners(clickListener: CustomButtonsClickListener) {
        binding.addButton.setOnClickListener {
            clickListener.onPlusClick(this, binding.addButton)
        }
        binding.minusButton.setOnClickListener {
            clickListener.onMinusClick(this, binding.minusButton)
        }
    }

This is how it look like "outside"

view.setCustomButtonsClickListeners(object : CustomButtonsClickListener {
                    override fun onPlusClick(view: View, button: ImageButton) {

                    }

                    override fun onMinusClick(view: View, button: ImageButton) {

                    }

                })

The Problem: I am getting error on object saying:
Object is not abstract and does not implement abstract member public abstract fun invoke()...

What is the method invoke() and how should I implement it? I would rather do it inside the View class so I don't have to do it while using the View somewhere in the app.


Solution

  • This looks like confusion over syntax.  The line:

    interface CustomButtonsClickListener : () -> Unit {
    

    creates an interface which extends () -> Unit (and goes on to add two methods to it).

    () -> Unit is the type of a function which takes no parameters and returns nothing useful.  You don't often need to know that function's name (as the lambda syntax hides it), but this is one of those corner cases where you find out that it's called… invoke()!

    (It's described in the documentation.)

    So you're defining an interface with three methods: one inherited from the parent interface, and the other two declared here.

    So of course, when you try to implement the interface but implement only two of those three methods, the compiler complains that you've forgotten the third.

    I guess you just want an interface with only your two new methods, so you can simply declare it with:

    interface CustomButtonsClickListener {