Companion objects

Java has a static keyword that can be applied to class members. Static members belong to a type, and not to an instance of a type. Kotlin doesn't have a static keyword, but can achieve this kind of functionality with some other language features. A common use case for static functions is grouping some utility functions inside a class. The collections class from the java.util package is a perfect example of this.

You can have this in Kotlin with functions declared at the file level or inside an object.

Another use of static members could be factory methods. This is usually done by hiding the class constructor from the outside with a private access modifier and delegating the instance construction to static methods.

Factory methods can be useful and sometimes they are preferred to having multiple constructors. In Kotlin, companion objects can be used to implement this design pattern.

Here's how a factory method design pattern would be implemented in Kotlin:

class User private constructor(val userId: String) {
companion object {
fun newUserWithEmail(email: String): User
{

return User(email)

}

fun newUserFromUUID(uuid: UUID): User {
return User(uuid.toString())
}
}
}

Accessing the companion object and its members is the same as if they were static:

val userFromEmail = User.newUserWithEmail("[email protected]")
val userFromUUID = User.newUserFromUUID(UUID.randomUUID())

The same as with normal objects, companion objects cannot have constructors, but can extend other classes and implement interfaces.

Let's see what the compiler does in the case of our User class and its companion object. This is how would it look if it was compiled from Java:

public class User {

private String userId;

private static final User.Companion COMPANION = new User.Companion();

private User(String userId) {
this.userId = userId;
}

public static final class Companion {

private Companion() {

}

public static User newUserWithEmail(String email) {
return new User(email);
}

public static User newUserFromUUID(UUID uuid) {
return new User(uuid.toString());
}
}
}

From this code, you can also see how you would access a companion object's members from Java: first by accessing the outer type and then the companion public field.

Companion objects can also have names. By default, if you don't specify a name the compiler will name the class companion. Here's a companion object with an explicit name definition:

class Outer {
companion object Inner {
fun saySomething() {
println("Hello")
}
}
}

Changing the name of a companion doesn't change how we access it. We don't have to specify the name of the companion object; it is optional. We can access its members from the outer type, as you can see here:

Outer.saySomething()
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.211.233