Define an object or a class with only a companion object?

I came across a class defined as :

sealed class SomeClass {
   companion object {
       large number of members...
   }
}

Is there any value in defining it as above or would the simpler solution be :

object SomeClass {
    large number of members...
}
1 Like

There is a difference: you can extend the sealed class while you cannot extend the object. This has other consequences. Consider the following example. If it would be a normal object the function f would be available for everyone.

sealed class A {
    companion object {
        @JvmStatic
        protected fun f() {}
    }
}

class B : A() {
    init {
        f()
    }
}
2 Likes

I don’t really see a need for the class to be sealed in my case. There are no external modules that will be using it/trying to use it.

Is that the only difference and if it is, is there any reason I shouldn’t just convert it to an object? (Just so that it’s a simpler implementation…?)

1 Like

Well, it really depends on the actual code you have.

First, converting it into an object will need additional code, imports, etc. You won’t be able to use a func() any more.

Also, sealed classes have the advantage of when, see Sealed Classes and When Expression.

You might have to change all those when structures, adding an else branch.

1 Like

That when expression is very interesting, thanks!

I’ve had to change some imports to remove Companion, but thankfully only in one place.

I’m not following the “You won’t be able to use a func() any more”?

1 Like

I mean you could just use func() to call function from the companion, but if you have an object you have to write SomeObject.func().

1 Like

Whoa. I didn’t realize that was a thing.

It still seems to work though, I can still call the functions directly without specifying the SomeObject.

I am still importing the functions themselves.
import com.SomeObject.getStatus

Where previously it was
import com.SomeObject.Companion.getStatus

1 Like

Another option is to not use any kind of object and just create the functions/members directly in the file. IE, if you currently have:

object Helpers {
    const val MY_NAME = "John"
    fun upperCaseName(): String = MY_NAME.toUpper()
}

You could simply put them directly into the file:

const val MY_NAME = "John"
fun upperCaseName(): String = MY_NAME.toUpper()
2 Likes