3
3
.
.
4
4
S
S
t
t
r
r
u
u
c
c
t
t
u
u
r
r
e
e
s
s
I
I
n
n
f
f
o
o
This chapter covers complex structures: Objects, Classes, Interfaces
Which contain Members: Fields, Properties, Methods
Which can be injected using: Extensions
Advanced features include: Interface Delegation, Companion Object
Syntax Overview
//DECLARATIONS.
interface InterfaceA { } //Interface
open class Person { open fun displayName() { print(name) } } //Parent
Class
object Soldier : Person, InterfaceA, InterfaceB { ... } //Object
class Soldier(var name: String, age: Int) : Person, InterfaceA, InterfaceB { ... init{}... }//Child Class
fun Person. displayName() { print("Hello $name") } //Extension
override fun sayHello() { super.displayName(); println("Hello $name") }
constructor(name: String) : super(name) { println("Secondary Constructor") } //Call Parent's
Constructor
constructor(name: String) : this (name) { println("Secondary Constructor") } //Call Primary
Constructor
//COMPANION OBJECT (Implements static members).
class Person {
companion object Companion {
@JvmStatic val name = "John"
@JvmStatic fun greet(age: Int) : String { return "$name is $age years old" }
}
}
O
O
b
b
j
j
e
e
c
c
t
t
s
s
Objects
have no Constructors
can extend single Class (Extended Class & overridden Method must be open. Use super to reference Parent.)
can Implement multiple Interfaces.
Use Companion Object and @JvmStatic to implement static Class Members.
Basic Object Syntax
object Soldier : Person, InterfaceA, InterfaceB { ... }
Object
//===========================================================================================================
// OBJECT: Person
//===========================================================================================================
object Person {
val age = 20
fun greet(name: String) { println("$name is $age years old") }
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
Person.greet("John") //John is 20 years old
}
Companion Object
//===========================================================================================================
// CLASS: Person
//===========================================================================================================
class Person {
companion object MyCompanion {
@JvmStatic val age = 20
@JvmStatic fun greet(name: String) { print("$name is $age years old") }
}
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
println("Hello ${Person.age}") //Call static Property using Class name.
Person.greet("John") //Call static Method using Class name.
}
C
C
l
l
a
a
s
s
s
s
Class has
optional Constructors
Primary Constructor (var & val Parameters are converted into Properties)
Secondary Constructors (If both exist Secondary must call Primary)
can extend single Class (Extended Class & overridden Method must be open. Use super to reference Parent.)
can Implement multiple Interfaces.
Use this to reference members.
Basic Class Syntax
class Soldier constructor(name: String, age: Int) : Person, InterfaceA, InterfaceB { ... }
Primary & Secondary Constructors
//===========================================================================================================
// CLASS: Person
//===========================================================================================================
class Person(public var name: String, age: Int) { //Variable Parameters are converted into Properties.
private var age : Int = 0 //Declare Properties.
init { this.age = age } //Primary Constructor Implementation.
constructor(name: String) : this(name, 50) { println("Constructed $name") } //Call Primary Constructor
fun greet() { println("$name is $age years old") } //Method.
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
var person = Person("John", 20) //Call Primary Constructor
person = Person("John") //Call Secondary Constructor
person.greet() //Call public Method: "John is 50 years old"
print(person.name) //Call public Property: "John"
}
Extend Class
//===========================================================================================================
// PARENT CLASS: Person
//===========================================================================================================
open class Person(var name: String) { //open allows Class to be extended
open fun greet() { println(name) } //open allows Method to be overriden
}
//===========================================================================================================
// CHILD CLASS: Soldier
//===========================================================================================================
class Soldier : Person { //Extend from Person Class
constructor(name: String) : super(name) { super.greet() } //Call Parent's Constructor & Method
override fun greet() { println("Hello $name") } //Override Parent's Method
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
var soldier = Soldier("John") //Create Object from Class Soldier.
soldier.greet() //Reference overriden method.
println(soldier.name) //Reference inherited Property.
}
I
I
n
n
t
t
e
e
r
r
f
f
a
a
c
c
e
e
s
s
Structs & Classes can Implement multiple Interfaces. Abstract Methods must be and Default Methods can be overridden.
Interface Delegation is when Class uses an existing Object which already has Implementation of that Interface.
Interface Syntax
interface InterfaceA { }
interface InterfaceB { }
class Person : InterfaceA, InterfaceB { }
Interface
//===========================================================================================================
//INTERFACE: InterfaceA
//===========================================================================================================
interface InterfaceA {
abstract fun abstractMethod()
fun defaultMethod1() { println("defaultMethod1()") }
fun defaultMethod2() { println("defaultMethod2()") }
}
//===========================================================================================================
//CLASS: Person
//===========================================================================================================
class Person : InterfaceA {
override fun abstractMethod() { println("Overriden abstractMethod()" ) }
override fun defaultMethod1() { println("Overriden defaultMethod1()" ) }
}
//===========================================================================================================
//FUNCTION: main
//===========================================================================================================
fun main() {
var person = Person()
person.abstractMethod() //Call overriden Abstract Method
person.defaultMethod1() //Call overriden Default Method
person.defaultMethod2() //Call Parent's Method
}
Interface Delegation
//INTERFACE: InterfaceA
interface InterfaceA {
abstract fun abstractMethod()
}
//CLASS: Person
class Person : InterfaceA {
override fun abstractMethod() { println("Overriden abstractMethod()" ) }
}
//CLASS: Soldier
class Soldier(var person: Person) : InterfaceA by person { }
//===========================================================================================================
//FUNCTION: main
//===========================================================================================================
fun main() {
var person = Person()
var soldier = Soldier(person) //We will use this Objet's Interface Implementation
soldier.abstractMethod() //Using Implementation from Person Class
}
M
M
e
e
m
m
b
b
e
e
r
r
s
s
:
:
F
F
i
i
e
e
l
l
d
d
s
s
,
,
P
P
r
r
o
o
p
p
e
e
r
r
t
t
i
i
e
e
s
s
,
,
M
M
e
e
t
t
h
h
o
o
d
d
s
s
var & val Parameters of Primary Constructor are automatically converted into Properties.
Members are public by default (access also outside of the Class). Can be private (access from members only).
Members: Fields, Properties, Methods
//===========================================================================================================
// CLASS: Person
//===========================================================================================================
class Person {
//DECLARE FIELD.
private var age : Int = 0
//DECLARE PROPERTY.
private var name : String = "" //Data Type returned by get() & input into set(value).
get() { return "Hello $field" } //Optional
set(value) { field = value } //Optional
//DECLARE METHOD.
public fun greet() {
println("$name. You are $age years old.") //Calls get().
}
//DECLARE CONSTRUCTOR.
constructor(name: String, age: Int) {
this.name = name //Calls set(). Use this to reference Property.
this.age = age
}
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
var person = Person("John", 20)
person.greet() //Call public member.
}
E
E
x
x
t
t
e
e
n
n
s
s
i
i
o
o
n
n
s
s
Extension is ability to add Properties & Methods to already existing Class.
Extension Property
must be declared inside Class Scope (can't be added inside a Method)
can't have Backing Field so you can't use Keyword field inside it (use Backing Properties to store data)
Extension Properties & Methods
//===========================================================================================================
// CLASS: Person
//===========================================================================================================
class Person(var name : String) { }
//===========================================================================================================
// CLASS: Soldier
//===========================================================================================================
class TestClass {
//ADD EXTENSION PROPERTY.
val Person.greet : String
get() { return "Hello $name" } //REFERENCE name FROM EXTENDED CLASS.
//ADD EXTENSION METHOD.
fun Person.sayHello() {
print("Hello $name") //REFERENCE name FROM EXTENDED CLASS.
}
//TEST METHOD.
fun test() {
var john = Person("John")
println(john.greet) //CALL EXTENSION PROPERTY.
john.sayHello() //CALL EXTENSION METHOD.
}
}
//===========================================================================================================
// FUNCTION: main
//===========================================================================================================
fun main() {
var testClass = TestClass()
testClass.test()
}