Saturday, April 14, 2012

Kotlin - Basics by Example



Extending my Basics by Example series to a new language :D. today's version of the post written in Kotlin.

You can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you the basics of the Programming Language.

There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2010/08/new-series-languages-basics-by-example.html 


Greetings Program - Verbose
// Kotlin Basics
package com.series.basics

import java.util.Calendar
import java.util.GregorianCalendar
import java.util.Scanner
import java.lang.System

// (Main) Constructor
public class Greet() {
    // Fields or Attributes are Properties
    private var _message: String = ""
    private var _name: String = ""
    private var _loopMessage: Int = 0
    // Properties
    public var Message : String
        get() {
            return this._message
        }
        set(value) {
            this._message = this.Capitalize(value)
        }
    public var Name : String
        get() {
            return this._name
        }
        set(value) {
            this._name = this.Capitalize(value)
        }
    public var LoopMessage : Int
        get() {
            return this._loopMessage
        }
        set(value) {
            this._loopMessage = value
        }
    // Overloaded/Secondary Constructor
    public this(val message: String, val name: String, val loopMessage: Int) : this() {
        this._message = message
        this._name = name
        this._loopMessage = loopMessage
    }
    // Method 1
    private fun Capitalize(val value: String) : String {
        // "if-then-else" statement
        if (value.length > 0)
            return value[0].toString().toUpperCase() + value.substring(1,value.length)
        else
            return ""
    }
    // Method 2
    public fun Salute() {
        // "for" statement
        for(i in 1..this._loopMessage) {
            println("${this._message} ${this._name}!")
        }
    }
    // Overloaded Method
    // No Overloaded Methods Support. New methods instead.
    // Method 2.1
    public fun Salute21(val message: String, val name: String, val loopMessage: Int) {
        // "while" statement
        var i: Int = 1
        while (i <= loopMessage) {
            println("${this.Capitalize(message)} ${this.Capitalize(name)}!")
            i++
        }
    }
    // Overloaded Method
    // No Overloaded Methods Support. New methods instead.
    // Method 2.2
    public fun Salute22(val name: String) {
        // "switch/case" statement is not supported
        // using match statement instead
        val dtNow: Calendar? = Calendar.getInstance()
        val t: Int? = dtNow?.get(Calendar.HOUR_OF_DAY)
        when (t) {
            6,7,8,9,10,11 -> this._message = "good morning,"
            12,13,14,15,16,17 -> this._message = "good afternoon,"
            18,19,20,21,22 -> this._message = "good evening,"
            23,0,1,2,3,4,5 -> this._message = "good night,"
            else -> this._message = "huh?"
        }
        println("${this.Capitalize(this._message)} ${this.Capitalize(name)}!")
    }
}

// Console Program
public fun main(val args: Array<String>) {
    // Define object of type Greet and Instantiate Greet. Call Constructor
    val g:Greet = Greet()
    // Call Set Properties
    g.Message = "hello"
    g.Name = "world"
    g.LoopMessage = 5
    // Call Method 2
    g.Salute()
    // Call Overloaded Method 2.1 and Get Properties
    g.Salute21(g.Message, "kotlin", g.LoopMessage)
    // Call Overloaded Method 2.2
    g.Salute22("carlos")
    // Stop and exit
    println("Press any key to exit...")
    // following code not working due to 'System.in' being considered as 'in' language keyword
    // Error message: Expecting an element
    //val ins: Scanner = Scanner(System.in)
    //var line: String? = ins.nextLine()
    //ins.close()
}

Greetings Program - Minimal
// Kotlin Basics
import java.util.Calendar
import java.util.GregorianCalendar
import java.util.Scanner
import java.lang.System

// (Main) Constructor
class Greet() {
    // Fields or Attributes are Properties
    private var _message: String = ""
    private var _name: String = ""
    private var _loopMessage: Int = 0
    // Properties
    var Message : String
        get() {
            return _message
        }
        set(value) {
            _message = Capitalize(value)
        }
    var Name : String
        get() {
            return _name
        }
        set(value) {
            _name = Capitalize(value)
        }
    var LoopMessage : Int
        get() {
            return _loopMessage
        }
        set(value) {
            _loopMessage = value
        }
    // Overloaded/Secondary Constructor
    this(message: String, name: String, loopMessage: Int) : this() {
        _message = message
        _name = name
        _loopMessage = loopMessage
    }
    // Method 1
    private fun Capitalize(value: String) : String {
        // "if-then-else" statement
        if (value.length > 0)
            return value[0].toString().toUpperCase() + value.substring(1,value.length)
        else
            return ""
    }
    // Method 2
    fun Salute() {
        // "for" statement
        for(i in 1.._loopMessage) {
            println("${_message} ${_name}!")
        }
    }
    // Overloaded Method
    // No Overloaded Methods Support. New methods instead.
    // Method 2.1
    fun Salute21(message: String, name: String, loopMessage: Int) {
        // "while" statement
        var i = 1
        while (i <= loopMessage) {
            println("${Capitalize(message)} ${Capitalize(name)}!")
            i++
        }
    }
    // Overloaded Method
    // No Overloaded Methods Support. New methods instead.
    // Method 2.2
    fun Salute22(name: String) {
        // "switch/case" statement is not supported
        // using match statement instead
        val dtNow = Calendar.getInstance()
        val t = dtNow?.get(Calendar.HOUR_OF_DAY)
        when (t) {
            6,7,8,9,10,11 -> _message = "good morning,"
            12,13,14,15,16,17 -> _message = "good afternoon,"
            18,19,20,21,22 -> _message = "good evening,"
            23,0,1,2,3,4,5 -> _message = "good night,"
            else -> _message = "huh?"
        }
        println("${Capitalize(_message)} ${Capitalize(name)}!")
    }
}

// Console Program
fun main(args: Array<String>) {
    // Define object of type Greet and Instantiate Greet. Call Constructor
    val g = Greet()
    // Call Set Properties
    g.Message = "hello"
    g.Name = "world"
    g.LoopMessage = 5
    // Call Method 2
    g.Salute()
    // Call Overloaded Method 2.1 and Get Properties
    g.Salute21(g.Message, "kotlin", g.LoopMessage)
    // Call Overloaded Method 2.2
    g.Salute22("carlos")
    // Stop and exit
    println("Press any key to exit...")
    // following code not working due to 'System.in' being considered as 'in' keyword
    // Error message: Expecting an element
    //val ins: Scanner = Scanner(System.in)
    //var line: String? = ins.nextLine()
    //ins.close()
}


And the Output is:




Auto-Implemented Properties in Kotlin

Auto-implemented properties enable you to quickly specify a property of a class without having to write code to Get and Set the property. In Kotlin, there's no way to declare a field. All you have is properties. Read/write properties are declared with the var keyword, and read-only ones – with val keyword.

// Kotlin Basics
class AutoImplementedProperties() {
    // Fields or Attributes are Properties
    var Message: String = ""
    var Name: String = ""
    var LoopMessage: Int = 0
    // Methods
    fun Salute() {
        println("${Message} ${Name} ${LoopMessage}!")
    }
}

// parameters of main constructor become properties of the class
class MainConstructorProperties(var Message: String, var Name: String, var LoopMessage: Int) {
    // Methods
    fun Salute() {
        println("${Message} ${Name} ${LoopMessage}!")
    }
}
// if you want private properties for the ones sent to the main constructor
// use the private modifier before each var/val declaration
/*class PropertiesFromConstructorParams(private var Message: String
                                      , private var Name: String
                                      , private var LoopMessage: Int) {
    // pass
}
*/

fun main(args: Array<String>) {
    val g = AutoImplementedProperties()
    // Call Set Properties
    g.Message = "hello"
    g.Name = "world"
    g.LoopMessage = 5
    // print them out
    g.Salute()
    // and print them again using Get Properties
    println("${g.Message} ${g.Name} ${g.LoopMessage}!")

    println()

    val p = MainConstructorProperties("bye","carlos",1)
    p.Salute()
    // Call Set Properties
    p.Message = "hello"
    p.Name = "world"
    p.LoopMessage = 5
    // print them out
    p.Salute()
    // and print them again using Get Properties
    println("${p.Message} ${p.Name} ${p.LoopMessage}!")

}

And the output is:

No comments:

Post a Comment