20

I'm pretty new to kotlin and I was wondering if it's possible, and if it's against best practice to access methods and variables that are outside a companion object, from within the companion object.

For example

class A {
    fun doStuff(): Boolean = return true

    companion object{
        public fun stuffDone(): Boolean = return doStuff()
    }
}

or something like that

Thank you

Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
alessandro gaboardi
  • 889
  • 3
  • 11
  • 26

3 Answers3

39

doStuff() is an instance method of a class; calling it requires a class instance. Members of a companion object, just like static methods in Java, do not have a class instance in scope. Therefore, to call an instance method from a companion object method, you need to provide an instance explicitly:

class A {
    fun doStuff() = true

    companion object {
        fun stuffDone(a: A) = a.doStuff() 
    }
}
yole
  • 92,896
  • 20
  • 260
  • 197
  • 1
    Thank you, so if i want to access it in a static way i could put doStuff() inside the companion object. But that would make it public right? – alessandro gaboardi Apr 03 '17 at 09:40
  • 1
    Yes, you can do that. All members in Kotlin are public by default, regardless of whether you define them in a class or in a companion object. If you don't want it to be public, just add a `private` modifier. – yole Apr 03 '17 at 10:01
2

You can also call functions that are outside of companion object block.

class A {
    fun doStuff() = true

    companion object {
        val a = A()
        fun stuffDone() = a.doStuff() 
    }
}
Uddhav P. Gautam
  • 7,362
  • 3
  • 47
  • 64
0

A correct way to do what you want is:

  1. create a instance of your main class inside Companion Objects
  2. initialize the instance when you instance the Main Class
  3. call the instance of the class when you need to call methods, set or get variables.

For a better control and better decouple level, you should access/set/get stuff from the main class (A) from the Companion Object instead of calling getInstance() to access the Main Class stuff.

Example:

 class A {
        
        private val myPrivateVariable:String = "MY_STUFF"
       
        init{
            setupInstance(this@A)
        }
        
        companion object{
           private val instance:A? = null
           
           fun setupInstance(a:A){
               this.instance = a
           }
           
           //IF YOU WANT TO ACCESS CLASS A METHODS/VARIABLES DIRECTLY YOU CAN CALL IT
           fun getInstance():A{
               return this.instance?.let{
                   it
                   }?:throw NullPointerException("INSTANCE NOT SET YET")
           }
           
           //ACCESSING CLASS A VARIABLES FROM COMPANION OBJECT (BETTER ERROR CONTROL AND DECOUPLED)
           fun setMyVariable(string:String){
               this.getInstance().myPrivateVariable = string
           }
            
            fun getMyVariable(string:String) = this.getInstance().myPrivateVariable    
          
        }
    }
Erick Cabral
  • 141
  • 2
  • 7