Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin, how to assign callback implementation to a variable

Tags:

I'm trying to assign a callback implementation of an interface (defined inside a class A) to a variabile defined inside another class B. Let's say that class A has the interface OnSomethingHappens which defines a doSomething method.

Inside class B I've defined my callback variable like this:

private lateinit var callback:A.OnSomethingHappens

I need to create an instance of class A passing callback variabile to the constructor in this way:

myinstanceA = A(callback)

I'm trying to assign an instance of an anonymous class that implements A.OnSomethingHappens using this code:

callback = object : A.OnSomethingHappens {
   override fun doSomething(..){
      //here I put the implementation of this method
   }
 }

but the compiler says "expecting member declaration" for my callback variable and "name expected" for object. What I'm doing wrong?

Instead, I'm able to define and at the same time assign the callback variable in this way:

private var callback = object : A.OnSomethingHappens {
      override fun doSomething(..){
        //here I put the implementation of this method
      }
    }

Why? Which are the differences and a possible solution?

like image 732
user9257465 Avatar asked Mar 27 '18 10:03

user9257465


2 Answers

I'm trying to assign an instance of an anonymous class that implements A.OnSomethingHappens using this code: ...

This should work, but only inside a method:

class B {
    private lateinit var callback:A.OnSomethingHappens

    fun someMethod() {
        callback = object : A.OnSomethingHappens { ... }
    }
    ...
}

Given the error message and that private var compiles (which doesn't inside a method), you are trying to set it directly in the body of the class instead:

class B {
    private lateinit var callback:A.OnSomethingHappens

    callback = object : A.OnSomethingHappens { ... }
    ...
}

This is illegal: the only code you can write there is member definitions and init blocks.

Also, if you can initialize callback directly where it's defined or inside init, there's no point to lateinit in the first place.

like image 183
Alexey Romanov Avatar answered Sep 22 '22 12:09

Alexey Romanov


It's not obvious from the code snippets cut down to such small pieces, but your issue is that you're writing down the assignment inside the body of a class, but not inside a function.

Here's an example of a valid declaration and immediate assignment:

class A {
    var x: X? = X()
}

Here's an example of an invalid assignment, which places an arbitrary expression in the body of a class:

class A {
    lateinit var x: X

    x = X()        // expression placed inside the class body, invalid syntax
    someFunction() // extra example, calling functions here is invalid in the same way
}

Instead, you could put this initialization inside a function:

class A {
    lateinit var x: X

    fun initializeX() {
        x = X()
    }
}

Or inside an initializer block (in this case, you don't even need lateinit):

class A {
    var x: X

    init {
        x = X()
    }
}

While I couldn't explain how to solve your exact problem, because I can't quite understand what code is in which class, I hope these examples and explanation helped.

like image 34
zsmb13 Avatar answered Sep 20 '22 12:09

zsmb13