Kotlin Methods | Android Introduction #19
In this reading, you will explore the concept of receiver, examine the methods on String and review the use of conversion methods.
Receiver
If you want to call a method, you need to have an object. You can then call this method on an object.
For instance, when you have a class Dog with a method feed, to call this method outside the class, you need to first have an object of type Dog.
class Dog(val name: String) {
var hunger = 62
fun feed() {
println("Feeding $name")
hunger = 0
}
}
fun main() {
val dog = Dog("Rex")
dog.feed() // Feeding Rex
}
Notice that an instance of type Dog is a part of the feed method call. Inside the method, you use the name and hunger properties from the object that was used during the call. In a way, it is similar to defining feed as a top-level function and passing Dog as an argument:
class Dog(val name: String) {
var hunger = 62
}
fun feed(dog: Dog) {
println("Feeding ${dog.name}")
dog.hunger = 0
}
fun main() {
val dog = Dog("Rex")
feed(dog) // Feeding Rex
}
The essential difference is that in methods, you access class members implicitly, so, for instance, using just name, not dog.name. How does it work?
When you call a method, the object of their class is passed to their body. It is called a receiver. It can be accessed using this keyword, also known as receiver reference. So, if you want to reference an object used to call a method inside this method, use the this keyword.
class Dog(val name: String) {
var hunger = 62
fun feed() {
val currentDog: Dog = this
println("Feeding ${currentDog.name}")
currentDog.hunger = 0
}
}
fun main() {
val dog = Dog("Rex")
dog.feed() // Feeding Rex
}
When you call methods or properties inside methods, such as when you call name, you are calling methods or properties on the receiver, so it’s like calling this.name.
class Dog(val name: String) {
var hunger = 62
fun feed() {
println("Feeding ${this.name}")
this.hunger = 0
}
}
fun main() {
val dog = Dog("Rex")
dog.feed() // Feeding Rex
}
However, there is a rule in most programming languages that methods or properties can be called on this explicitly, so this. can generally be skipped. However, sometimes you may want to use this explicitly.
One example might be when you have a method parameter and class property with the same name. Like in the below class, there is a property name and a method changeName with a parameter name. So, if you use name inside the class, you will have a value of the parameter. To access the property, use this.name.
class User(var name: String) {
fun changeName(name: String) {
println("Changed name from ${this.name} to $name")
this.name = name
}
}
fun main() {
val user = User("Alpha") // Changed name from Alpha to Beta
user.changeName("Beta") // Beta
println(user.name)
}
Methods on String
Previously, you may have observed some methods defined on String. Let’s review them:
- uppercase returns the same text, but with all characters in uppercase.
- lowercase returns the same text, but with all characters in lowercase.
- replace changes all the repetition of one string into another.
fun main() {
val text = "Some Text"
println(text.uppercase()) // SOME TEXT
println(text.lowercase()) // some text
println(text.replace("Text", "NewText")) // Some NewText
println("A B A C".replace("A", "G")) // // G B G C
}
Conversion Methods
Other basic types have many useful methods, starting from the methods used to convert from one type to another. All the numbers can be transformed into other basic types of numbers using methods starting from to and ending with the name they should be transformed to. For instance, to transform Int or Long to Float, use toFloat() as in the example below.
fun main() {
val i: Int = 10
val l: Long = i.toLong()
val f1: Float = i.toFloat()
val f2: Float = l.toFloat()
println(f1) // 10.0
println(f2) // 10.0
}
Although this was already covered earlier in the course, it should now be clear that these are the methods defined in all the classes representing numbers.