Introduction to Kotlin: Classes, Constructors, Encapsulation, Inheritance, and Interfaces
Table of contents
Classes
Class is a group of similar entities and can be defined using the class
keyword in Kotlin.
class Person { /*...*/ }
Objects (i.e. instances) of a class, can be created by calling its constructor. Via Objects, we can access the properties of the class.
Hence, an object is a self-contained component that consists of functions & properties.
val rahul = Person()
//creating an object named rahul of class Person
class Car { // creating class
var model = "G20" //defining its properties
var color = "Red"
fun drive(): String { return "Start" } //and methods
//...
}
fun main() {
val car1 = Car() //creating object of type Car
car1.color = "Blue" //accessing its methods and properties
print(car1.model)
print(car1.drive())
}
Access ( Visibility ) Modifiers in Kotlin :
used for setting the access level to classes, variables, functions, and constructors.
private: means methods, variables, and constructors are only visible inside their declared class
protected: means methods, variables, and constructors are only visible inside their declared class & its corresponding subclasses
internal: members are visible inside the same module
public: accessible from everywhere
Constructor
A constructor is a special member function that is the first method to be invoked when an object of a class is created. Classes in Kotlin have one primary constructor and can have one or more secondary constructors.
Its role is to initialize variables and properties. Hence, when no constructor is specified an empty default constructor is created by Kotlin in the background.
class Person constructor(firstName: String) { /*...*/ }
//or
class Person(var firstName: String) { /*...*/ }
//f the primary constructor doesn't have any access modifier,
//the constructor keyword can be neglected.
Primary Constructor is declared in the class header. It initializes a class instance, and its properties in the class header.
However, the class header can't contain any runnable code. Runnable code that needs to be executed during the object creation, should be declared under the initializer block using the init
keyword.
Parameters declared under the primary constructor can be used inside the class, in the initializer block, defining properties, etc. The constructor parameter can be of any type and contain a default value.
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name"
init {
println("First initializer block that prints $name")
}
val secondProperty = "Second property: ${name.length}"
init {
println("Second initializer block that prints ${name.length}")
}
}
Secondary Constructors are declared in the class body, and can also perform logic.
class Sum{
constructor() //empty constructor
constructor(a: Int, b:Int){
print("Sum is: $(a+b)")
}
constructor(a: Int, b:Int, c:Int){
print("Sum is: $(a+b+c)")
}
}
//hence object creation accepts all 0,2 and 3 number of parameters
Encapsulation
Mechanism to ensure that the data within an object is kept private & safe from external modifications. This concept is achieved through access modifiers.
class Car { // creating class
private var model = "G20" //defining its properties
var color = "Red"
fun drive(): String { return "Start" } //and methods
//...
}
fun main() {
val car1 = Car() //creating object of type Car
car1.color = "Blue" //accessing its methods and properties
//can't set car1.model as private.
//can't get car1.model as private.
// print(car1.model)
print(car1.drive())
}
//however modifying the set & get properties of private variable.
class Car {
private var model = "G20"
private set //can't change model value of object
get //can't read model value of object
//..
}
Inheritance
Inheriting class properties & methods from one class to another can be achieved with the concept of inheritance.
subclass - the class that inherits from another class
superclass - the class that is being inherited from
All classes in Kotlin have a common superclass Any
which has three methods equals()
, hashCode()
, and toString()
. Thus, these methods are defined for all Kotlin classes.
By default, Kotlin classes are final – they can't be inherited. To make a class inheritable, mark it with the open
keyword. To declare inheritance from a class we use the extends :
keyword.
open class classA(){ //other class can inherit from the classA
var name = "John"
fun add(){ .. }
}
class classB : classA(){
..
}
fun main(){
var obj = classB()
print(obj.name) //can access properties of parent through child
}
Function Overriding in Kotlin :
To avoid compilation errors, when both the member functions of the subclass and the superclass have the same name we need to override the method.
open class Shape {
open fun draw() { /*...*/ } //created open
final fun fill() { /*...*/ } //use final keyword to restric override
}
class Circle() : Shape() {
override fun draw() { /*...*/ } //over-ridden
}
Abstract Classes
Abstract classes act as template classes and can not be instantiated only subclassed. They establish an is-a relationship with other classes. May Contain -
abstract methods ( functions with a body )
methods with body
abstracts variables
variables
abstract class Company {
abstract val numbrOfEmployees : Int
abstract fun giveSalaryToEmployees()
fun annualTargetPlanning() { ... }
}
Classes that extend an Abstract class need to override all its abstract members.
class Google() : Company() {
override val numberOfEmployees: Int = 200
override fun giveSalaryToEmployees() {
Log.d("Salary","Google Salary")
}
}
Interfaces
Interface acts as a collection of abstract methods & methods with default implementations. They establish a can-do relationship with other classes. As a class in Kotlin can't inherit more than one class, Hence multiple inheritance requires the inheritance of Interfaces.
interface Swimmable {
var test: String //abstract property
//var test2: String = "CANNOTHOLDSTATE"
//cannot do this inside of the interface(cannot hold state in interfaces)
fun swim() // abstract method
// method with default implementation
fun live() {
println("Live in the moment!")
}
}
Multiple Inheritance is possible with Interfaces. A Kotlin class can only inherit one superclass, but it can implement multiple interfaces.