Object vs object declaration


#1

Hi all, can you clarify some things for me as I am quite new to Kotlin?
in this code:
class MainSample {

    private fun foo() {

    }

    fun someFunctionInClass() {
        val sample = Sample(otherObj)
        val sample2 = Sample(object : Sample.Test {
            override fun sampleFun() {
                foo()
            }
        })
    }

    val otherObj = object : Sample.Test {
        override fun sampleFun() {
            foo()
        }
    }

    object otherObj2 : Sample.Test {
        override fun sampleFun() {
            foo() // error here!!
        }
    }

}

what is the difference here between those objects? why without val I can not access functions/ variables from outer scope ?
Thanks in advance


#2

From my phone:

  • otherObj is an instance of an anonymous class
  • otherObj2 is a class (btw it should be OtherObj2) that contains an implicite reference a single instance

They are pretty much the same thing in usage (you I’ll see the difference when using them from java)

I have a doubt on whether obj2 is bound to main sample class or instance…

I’ll give you more info when I can access my computer if there is no one answered you before


#3

Just to expand on the previous post and clarify certain aspects of it.

otherObj2 is a static member of the MainSample class i.e. it is independent of any particular instance of that class. In particular, it knows nothing about 'this'.

foo is a private instance method of MainSample and so this.foo() - effectively what foo() means - cannot be accessed from within otherObj2.

On the other hand otherObj is an instance property of the MainSample class which is assigned an object expression. Object expressions are similar to anonymous inner classes in Java and can access members from the enclosing scope i.e. it can call this.foo() in this example.

This link to the documentation on objects may help to get all this clear in your mind.


#4

answering to myself too:

Like inner classes, object are static by default (bound to the class).

small code to explain this :


class Main{

    companion object {
        fun foo() {
            println("function")
        }
    }

    fun foo() {
        println("method")
    }

    fun someFunctionInClass() {
        val sample = Sample(otherObj)
        val sample2 = Sample(object : Sample.Test {
            override fun sampleFun() {
                foo()
            }
        })
    }

    val otherObj = object : Sample.Test {
        override fun sampleFun() {
            foo()
        }
    }

    object otherObj2 : Sample.Test {
        override fun sampleFun() {
            foo() // error here!!
        }
    }
}

class Sample(otherObj: Test) {
    interface Test{
        fun sampleFun()
    }
}

fun main(args: Array<String>) {
    val main = Main()
    main.foo() // method
    main.otherObj
//    main.otherObj2 // does not compile
    Main.foo() // function
//    Main.otherObj // does not compile
    Main.otherObj2
}

so

They are pretty much the same thing in usage

was completly wrong