iotric Blog

MOBILE DEVELOPMENT

What’s new in Kotlin that Java lacks for Android development

Posted March 21, 2021 iotric

Kotlin has been declared as the official language for Android Development. So we decided to talk about it a little bit to get you started!

Java and Kotlin are totally interoperable, this means if we have two classes, one made in Kotlin and the other one in java, it can be easily used with each other.

Also we can convert any Java file to Kotlin by pressing ctrl + shift + alt + k (Windows) / cmd + shift + alt + k (Mac). Cool, isn’t it?

So, I’m going to divide this blog into small topics to make it easily understandable. I’m going to talk about the differences between Java and Kotlin and some of the new things that are added In this language.

Let’s Get Started!

Data Classes (POJOs)

A data class in Kotlin can be defined as : 
data class Money(val amount: BigDecimal, val currency: String)

or providing default values:
data class Money(val amount: BigDecimal = BigDecimal(100), val currency: String = "INR") 

A Java equivalent of this Kotlin data class will be : 
public class JavaMoney {
    String currency;
    int amount;

    public JavaMoney(int amount, String currency) {
        this.currency = currency;
        this.amount = amount;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        JavaMoney javaMoney = (JavaMoney) o;
        return amount == javaMoney.amount &&
                Objects.equals(currency, javaMoney.currency);
    }

    @Override
    public int hashCode() {
        return Objects.hash(currency, amount);
    }

    @Override
    public String toString() {
        return "JavaMoney{" +
                "currency='" + currency + '\'' +
                ", amount=" + amount +
                '}';
    }

    @NonNull
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) {
        Money money = new Money(BigDecimal.ONE, "$");
        money.getAmount(); // Now in java we can have getters and setters
    }
}


Here if we need to add/delete/update a single key we need to mess up with all the functions inside the java to make the change but for Kotlin data class, just add/update a variable inside the data class and you're done! 

No need to specify data type when initialising a variable :

val tickets = Money(BigDecimal(100), "$") //No need to tell the data type - Strongly type referenced. 
Tickets will automatically be of data type 'Money'.

Named parameters / copy :

val popcorn = tickets.copy(amount = BigDecimal(500), currency = "EUR")
val fuel = tickets.copy(amount = BigDecimal(500))
Here, we can copy all the properties of tickets into popcorn and can manipulate separate properties by naming them like amount = or currency = or both

Method Overriding :

In Kotlin we can provide default values to the parameters (Like we did above inside money class). Therefore that class can be initialised by default parameters and/or by providing specific values and/or by providing all the values.

val tickets = Money(BigDecimal(100), "$")
val popcorn = tickets.copy(amount = BigDecimal(500), currency = "EUR")
val popcorn = tickets.copy(currency = "EUR", amount = BigDecimal(500))
val popcorn = tickets.copy(currency = "EUR")
val popcorn = tickets.copy(amount = BigDecimal(500))
val popcorn = tickets.copy()

All the above mentioned initialisations are valid. 
//Named parameters, Interchangeable, Useful when there are a lot of parameters to pass and for overloading

Noticed that we have never used semicolons in our code? Well, semicolons are optional in Kotlin.

val and var :

val i = 100 // The value of i can never be changed, its fixed to 100

var i = 100 // The value of i can be changed at any time.

Property Comparison and Pointer Comparison :

//Property Comparison
if (tickets != popcorn) {
    println("they are different (Values)")
} else {
    println("they are same (Values)")
}

//Pointer comparison
if (tickets !== popcorn) {
    print("they are different (Objects)")
}

== (Property Comparison) //Only compares value
=== (Pointer comparison) //Compares if the object's memory are same or not (Are same objects or not)

Getter / Setters :

//In kotlin we only have properties instead of getters and setters
val javaMoney = JavaMoney(100, "$")
javaMoney.amount = 200 //No setter/getter (Setting the value)
javaMoney.currency // Getting the value

One more way to return values from a function :

fun sum(x: Int, y: Int) = x + y //No return type required, no curly braces required.

Single expression functions :

fun convertToDollars(money: Money) = when (money.currency) {
    "$" -> money
    "EUR" -> Money(money.amount * BigDecimal(1.10), "$")
    else -> throw IllegalStateException("not the currency you're interested in!")
}

Extension Functions

We can create extensions for any class, pre defined class or custom classes. There's no limit
//Extension Function (Have the scope of the package if defined outside of the class), not defined inside a class

fun BigDecimal.percent(percentage: Int) = this.multiply(BigDecimal(percentage)).divide(BigDecimal(100))

//Extension function to set visibility = View.GONE of a view
fun View.gone() {
    this.visibility = View.Gone
}

class Main() {
    var bd1 = BigDecimal(100)
    bd1.percent(10) //10 percent of 100

    someView.gone() //Set the visibility to View.GONE
}

Yes, In Kotlin we can define values and functions outside of the class, its scope will be the package in which that property/function is defined into. 

Inline Functions : (An evolved way to write extension functions)

infix fun Int.percentOf(money: Money) = money.amount.multiply(BigDecimal(this)).divide(BigDecimal(100))

class Main() {
    val tickets = Money(BigDecimal(100), "$")
    7 percentOf tickets //Using infix (returns 7 percent of popcorn)
}

Sealed / Open classes in Kotlin :

sealed class UserResult //Every class in kotlin is final by default hence cant be extended or use open
data class Success(val users: List<String>) : UserResult() //Extend user result
data class Failure(val message: String) : UserResult()

Open class can't be further extended by only those classes that are defined inside its scope can extent it. 

Kotlin has both objectoriented and functional constructs. You can use it in both OO and FP styles, or mix elements of the two. With first-class support for features such as higher-order functions, function types and lambdas, Kotlin is a great choice if you’re doing or exploring functional programming.

That’s All for now! These were not all the new things that were introduced in Kotlin but to give you a taste of it. Hope you enjoyed it! 🥳 Keep coming for more interesting blogs!

Leave a Reply



    Get In Touch!