2
votes

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

2
I truly wonder what you think is the point of companion objects. What you're describing is the semantics of member functions of the Person class.Marko Topolnik

2 Answers

2
votes

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.

0
votes

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).