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: