The object keyword does 2 things at the same time
- Defines a class
- Creates an instance of that class
There are 3 situations when it is used
Object declarations (singletons)
Singletons in OOP are used when you need just one instance of a class. An example would be the state of a video game.
In object declarations are allowed properties, methods, initilizer blocks etc. but not constructors since object declarations are created at the point of definition and never from calls to them. There can not be any:
var state = GameState()
Companion objects are used when you need to call the internals of a class from an function that does not need an instance.
- Accessing members of companion objects don’t need a name. To access the companion object just use the class name. Like in object declarations
- Companion objects are initialized when the corresponding class is loaded, on the other hand object declarations are lazily initialized, when accessed for the first time.
It is “kind of” a substitution of static in Java. Top level functions can be used in the same way with the difference that they can not access the private members of the class.
Companion objects as factory methods
The factory method pattern provide extra benefits to the standard object creation via constructors.
- They can be named accordingly with their purpose.
- The returned object can be a subclass of the class where it is declared.
- They can return old objects instead of creating new ones.
Only one companion object is allowed per class but we can name it for clarity if we want.
Companion objects and extension functions
If you want to separate certain logic from your class you can do it adding extension functions to a companion object.
Companion objects implementing an interface
Because companion objects can implement interfaces we could use the name of the containing class directly as an instance of an object implementing the interface.
Object expression are use to declare anonymous objects. Anonymous objects substitute Java’s anonymous inner classes.
The parameter of setAnimatorListener is an AnimatorListener object, using an object expression we declare and instantiate it directly on the function parameter. Note that there is no need to assign a name to it.
- Can implement more than one interface.
- Can access and modify non-final variables from the function where it is created.
- Are created every time they are executed. They aren’t singletons like object declarations.