Skip to content

Methods and Functions

Taras Koshkin edited this page May 31, 2017 · 3 revisions

Sections



First Function (and visibility)!

Java

public void myFirstMethod() { System.out.print("I did it!"); }

private void privateMethod() { System.out.print("This method is super private!"); }

protected void protectedMethod() { System.out.print("This method is super protected!"); }

void localMethod() { System.out.print("Local method!"); }

Kotlin

//there's no "local" access, default is Public
fun myFirsFunction() { print("I did it!") }

private fun privateFunction() { print("This method is super private!") }

protected fun protectedMethod() { print("This method is super protected!") }

//This is equivalent to local
internal fun internalMethod() { print("Local method!") }

Args and Overloads

Java

private String totalBalance(double amount, String currency) {
    return currency + String.valueOf(amount);
}

private String totalBalance(double amount) {
    return totalBalance(amount, "$");
}

Kotlin

//String gets a default argument of "$"
private fun totalBalance(amount: Double, currency: String = "$"): String {
	return "$currency$amount"
}

Named Arguments

Java

public String fullName(String firstName, String middleName, String lastName) {
    return firstName + " " + middleName + " " + lastName;
}

public void populateName() {
    //it helps to identify what variable is what, AND you don't need to follow the order
    System.out.println(fullName("Taras", "Oleg", "Koshkin"));
}

Kotlin

//Not everyone has middle name! Let's overload that
fun fullName(firstName: String, middleName: String = "", lastName: String): String {
    return "$firstName $middleName $lastName"
}

fun populateName() {
    //it helps to identify what variable is what AND you don't need to follow the order
    println(fullName("Taras", lastName = "Koshkin", middleName = "Oleg"))
}

Single Expression

Java

public double square(double x) { //java has no single expression
    return x * x;
}

Kotlin

fun square(x: Double): Double = x * x //notice you don't have to put "return"

Generics

Java

public <T> Future<T> createFuture(T t) { }

Kotlin

fun <T> createFuture(t: T): Future<T> { } //It's pretty much the same..

Extensions!!!

Java

public void slideInFromLeft(View view) {
    view.setTranslationX((-view.getWidth()));
    view.animate().translationX(0).setInterpolator(new AccelerateInterpolator()).start();
}

//After this Java kind of... can't do it

Kotlin

fun View.slideInFromLeft() {
    this.translationX = (-this.width).toFloat()
    this.animate().translationX(0.toFloat()).setInterpolator(AccelerateInterpolator()).start()
}

//Let's pass a function into an extension function...
inline fun ViewGroup.forEach(action: (View) -> Unit) {
    for (index in 0 until this.childCount) {
        action(this.getChildAt(index))
    }
}

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) {
    for (index in 0 until this.childCount) {
        action(index, this.getChildAt(index))
    }
}

fun sample() {
    val view: View = ...
    val viewGroup: ViewGroup = ...

    view.slideInFromLeft() // nice and concise
    
    viewGroup.forEach { } // it looks like a collection!
    viewGroup.forEachIndexed { index, view ->  } // and a little extra
}

Extension function within an extension function...

//Quick extension so you can add objects to the bundle when creating a fragment
inline fun Fragment.bundle(action: Bundle.() -> Unit): Fragment {
    val args = Bundle()
    args.action()

    this.arguments = args
}

//this is how to use it
fun instance(accountNumber: Long, isCheckingAccount: Boolean): Fragment {
    return BankFragment().bundle {
        putLong("accountNumber", accountNumber)
        putBoolean("isCheckingAccount", isCheckingAccount)
    }
}

Operators and more fun

operator fun ViewGroup.get(index: Int): View = getChildAt(index)
operator fun ViewGroup.minusAssign(child: View) = removeView(child)
operator fun ViewGroup.plusAssign(child: View) = addView(child)
operator fun ViewGroup.contains(child: View) = indexOfChild(child) != -1

fun runIt() {
	val views: ViewGroup = ...

	val first = views[0]
	views -= first
	views += first
	if (first in views) { }
}

//infix only works if you only have 1 argument in an extension function
infix fun View.isBackgroundColor(color: Color): Boolean = this.background == color

fun callInfix() {
    view isBackgroundColor Color.RED //looks like human language almost
}