Problem Statement
Explain companion objects, how they differ from Java static members, and common use cases.
Explanation
Companion objects declared with companion object inside a class provide a namespace for members that logically belong to the class rather than instances, accessed via the class name like ClassName dot memberName. Unlike Java static members which are not objects, companion objects are actual singleton objects that can implement interfaces, be passed as arguments, and participate in inheritance making them more flexible for polymorphism and dependency injection.
Common use cases include factory methods that create class instances with validation or custom initialization logic, constants and utility functions related to the class, and implementing interfaces at the class level for features like Parcelable in Android. You can give companion objects explicit names like companion object Factory, or implement interfaces like companion object colon JsonDeserializer for type-safe factories.
Companion objects can have extension functions allowing you to add functionality to classes even from outside their definition, useful for separation of concerns or adding Android-specific extensions. While they serve similar purposes to Java static members, companion objects being real objects enables patterns impossible with static members like dependency injection of companion object implementations or testing with mock companions.
