parsa
parsa

Reputation: 985

Kotlin - How to use a class property in a companion object

I was wondering if I can use a property of a class inside a companion object. for example take the instance bellow:

class Person1(val name: String, var age: Int){
    lateinit var surname: String
    companion object myc{
        var cname: String =""
        var cage: Int = 0
        fun constructor(cname: String, cage: Int){
            this.cage = cage
            this.cname = cname
        }
        fun changeAge(age: Int ?= 0){
//            access to surname or name or age 

        }
    }
}

i can't get access to any of the properties from Person1 class

and for instance lets say that we call the class or companion object as bellow:

val c1 = Person1.myc.constructor("john",10)
val c2= Person1("jack",20)

i can't call the changeAge() function through c1 or c2. the only place where i can use changeAge is through Person1.changeAge() when Person1 has not been instantiated with proper constructor. i was wondering if there is an alternative for these actions or if there aren't what is the point of having companion objects anyways

Upvotes: 6

Views: 10923

Answers (2)

Alexey Romanov
Alexey Romanov

Reputation: 170745

Nesting a class inside a class doesn't automatically give you access to an instance of this class, unlike in Java. The same applies for objects, including companion objects. companion just lets you refer to this object as Person1 in addition to Person1.myc.

Your fun constructor isn't a constructor; it's just a method called constructor.

Upvotes: 5

gil.fernandes
gil.fernandes

Reputation: 14611

This is regarding the purpose of companion objects:

I use companion objects to instantiate members which in Java would typically be static.

For example, if you have JUnit 4 test and the main service you want to test is static and you want to use the @BeforeClass class annotation. This is what you can do:

class ExcelDedupReportGeneratorTest {

    companion object {
        init {
            // things that may need to be setup before companion class member variables are instantiated
        }

        // variables you initialize for the class just once:
        var reportGenerator: ExcelReportGenerator? = null

        @BeforeClass @JvmStatic fun setup() {
            val messageSource = Mockito.mock(MessageSource::class.java)
            reportGenerator = ExcelDedupReportGenerator(messageSource)
        }
    }

    @Test
    fun whenWrite_ShouldWriteFile() {
        Files.newOutputStream(Paths.get("demoReport-dedup.xls")).use {
            reportGenerator?.write(ReportBeanProvider.createReportData(), it)
        }
    }
}

In this case the test class accesses the reportGenerator element of the companion which exists only once in memory (like a static member in Java).

Upvotes: 1

Related Questions