In this tutorial, we’ll be discussing the Object Oriented Programming concepts of Kotlin. We’ll discuss Kotlin Class in detail. We will also look at kotlin constructors, access modifiers and abstract class.
A class is a blue print defined which groups functions and properties. Classes in Kotlin are defined using the keyword class
followed by the class name. The body goes inside the curly braces.
class FirstClass {
}
An instance of the class is instantiated in the following way:
val firstClass = FirstClass()
var new = FirstClass() //here new is the name of the var.
Contrary to Java, new
isn’t a keyword in Kotlin. Classes by default are final in Kotlin. So the equivalent of the above definitions in Java would like something like this:
public final class FirstClass {
}
Hence, by default classes in Kotlin are not inheritable. To make a class non-final we need to append the keyword open
.
open class Me{
}
The open
annotation allows others to inherit from this class.
Let’s create a class with a few functions and a property. We’ll see how to access the functions and properties of that class. Furthermore, we’ll see how to set the member properties.
class User {
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
fun main(args: Array<String>) {
val user = User()
println(user.loggedIn) //false
user.logOn()
println(user.loggedIn) //true
user.logOff()
println(user.loggedIn) //false
user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.
}
The function main
belongs to the Test.kt
class. To access members and functions, we need to use the dot operator. A val
property can’t be set again using a dot operator.
Kotlin init block is defined as shown below.
class User {
init{
print("Class instance is initialised.")
}
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
The code inside the init
block is the first to be executed when the class is instantiated. The init
block is run every time the class is instantiated, with any kind of constructor as we shall see next. Multiple initializer blocks can be written in a class. They’ll be executed sequentially as shown below.
class MultiInit(name: String) {
init {
println("First initializer block that prints ${name}")
}
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array<String>) {
var multiInit = MultiInit("Kotlin")
}
//Following is printed in the log console.
//First initializer block that prints Kotlin
//Second initializer block that prints 6
Kotlin classes allow printing properties in the declaration itself by using the also
function as shown below.
class MultiInit(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array<String>) {
var multiInit = MultiInit("Kotlin")
}
//Following gets printed.
//First property: Kotlin
//First initializer block that prints Kotlin
//Second property: 6
//Second initializer block that prints 6
Kotlin Constructors are special member functions that are used to initialize properties. Constructors in Kotlin are written and structured differently compared with Java. By default a class has an empty constructor as shown below:
class Student {
var name: String
val age : Int
init {
name = "Anupam"
age = 24
}
init {
name = "Anupam Chugh"
//age = 26
}
}
fun main(args: Array<String>) {
val student = Student()
println("${student.name} age is ${student.age}")
student.name = "Your"
//student.age = 26 //won't compile. age is val
println("${student.name} age is ${student.age}")
}
//Following is printed on the console:
//Anupam Chugh age is 24
//Your age is 24
Primary Constructors in Kotlin are defined in the class header itself as shown below.
class User(var name: String, var isAdmin: Boolean) {
init {
name = name + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $isAdmin")
}
}
The primary constructors definition goes inside the class header. We’ve defined the property types(val/var) in the constructor itself. Note: Unless stated as a var
, by default, constructor arguments are val
.
class User(name: String, isAdmin: Boolean)
In the above code, both name and isAdmin can’t be reassigned. Alternatively, we can aslo assign the constructor arguments to the member properties in the class as shown below.
class User(name: String, val isAdmin: Boolean) {
var username = name
val _isAdmin = isAdmin
init {
username= username + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $_isAdmin")
}
}
fun main(args: Array<String>) {
var user = User("Anupam",false)
user.isAdmin = true //won't compile since isAdmin is val
user._isAdmin = true //won't compile. Same reason.
user = User("Pankaj",true)
}
//Following is printed in the log console.
//Author Name is Anupam. Is Admin? false
//Author Name is Pankaj. Is Admin? true
Kotlin allows us to specify default values in the constructor itself as shown below.
class User(name: String, var website: String = "JournalDev") {
init {
println("Author $name writes at $website")
}
init {
website = website + ".com"
println("Author $name writes at $website")
}
}
fun main(args: Array<String>) {
var user = User("Anupam","JournalDev")
user = User("Pankaj","JournalDev")
}
//Following is printed on the console:
//Author Anupam writes at JournalDev
//Author Anupam writes at JournalDev.com
//Author Pankaj writes at JournalDev
//Author Pankaj writes at JournalDev.com
Secondary Constructors are written inside the body of the class by prefixing with the keyword constructor
. Following example demonstrates the same.
class Student {
var name: String
val age : Int
constructor(name: String, age: Int)
{
this.name = name
this.age = age
}
fun printDetails()
{
println("Name is $name and Age is $age")
}
}
fun main(args: Array<String>) {
var student = Student("Anupam", 24)
student.printDetails()
}
//Following is printed in the console.
//Name is Anupam and Age is 24
The most common usage of secondary constructors comes in subclasses when you need to initialize the class in different ways. If the class contains a primary constructor, the secondary constructor must refer to it in its declaration. The declaration is done using this
keyword.
class Student(var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
//Following is printed in the log console:
//Name is Anupam and Age is 24
//Name is Anupam and Age is 24 Skill is Kotlin
init
block is used to initialise the member property skill
. The secondary constructor delegates to the primary constructor using : this
.
Up until now we’ve accessed and modified properties in a class using the dot operator on the instance of the class. Let’s use set
and get
syntax to see how we can customise the access.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
print(value)
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "Kotlin Classes"
name.post = ""
name.post = "Kotlin Data Classes Our Next Tutorial"
}
Following is printed in the log console:
Kotlin Classes
Exception in thread "main" java.lang.IllegalArgumentException: Enter a valid name
at Name.setPost(Test.kt:16)
at TestKt.main(Test.kt:78)
The field
variable in the setter saves the older value. Let’s add a getter.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
}
get() {
return field.capitalize()
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "kotlin classes"
println(name.post)
name.post = "kotlin data Classes our next Tutorial"
println(name.post)
}
//Following is printed:
//Kotlin classes
//Kotlin data Classes our next Tutorial
capitalize()
capitalizes the first letter of the string. Note: if the property is a val
, set
method won’t compile.
Visibility Modifiers are applicable on Constructors as well. Assigning a modifier to a Primary Constructor requires us to specify the keyword constructor
alongside the constructor in the class header.
class Student private constructor (var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
fun main(args: Array<String>) {
var student = Student("Anupam",24,"Kotlin")
student.printDetails()
}
//prints
//Name is Anupam and Age is 24 Skill is Kotlin
Private constructors can’t be called outside the class. In the above code, we can instantiate the class in a different function only using the secondary constructor.
Like Java, abstract
keyword is used to declare abstract classes in Kotlin. An Abstract class can’t be instantiated. However, it can be inherited by subclasses. By default, the members of an abstract class are non-abstract unless stated otherwise.
abstract class Person(name: String) {
init {
println("Abstract Class. init block. Person name is $name")
}
abstract fun displayAge()
}
class Teacher(name: String): Person(name) {
var age : Int
init {
age = 24
}
override fun displayAge() {
println("Non-abstract class displayAge function overridden. Age is $age")
}
}
fun main(args: Array<String>) {
val person = Teacher("Anupam")
person.displayAge()
}
//Following is printed in the console.
//Abstract Class. init block. Person name is Anupam
//Non-abstract class. Age is 24
Note: Abstract classes are by default open
. So adding an open modifier to allow subclassing isn’t required. override
keyword is used to override a method in the subclass. We’ve covered the basics of kotlin classes in this tutorial. There’s a lot more still there such as Data Classes, Sealed Classes, Inheritance etc. We’ll be covering them in the upcoming tutorials. References : Kotlin Docs
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Hello, thank for your tutorials but your code is not clear to understand please make it clear if you made this website for educational purpose thank.
- Ahmadullah
Explained nicely.
- Aniket Malviya