kotlin class

kotlin class constructors package import

In support of object-oriented programming (OOP), Kotlin provides a class construct. The syntax is much more concise than languages like Java and C#, but it’s also still easy to use and read.

Class in kotlin

Classes are created with the class keyword

Primary constructor parameters go in the class header

  var parameters are read-write, and val parameters are read-only Class instances are created without the new keyword

Think of it like you’re calling a function Classes can have initializer blocks

Classes can have properties and methods (functions) Classes can have nested classes and inner classes

Classes are created with class keyword:

class Foo

class Person constructor(var firstName: String, var lastName: String)

The primary constructor is part of the class header. If the primary constructor does not have any annotations or visibility modifiers, the constructor keyword can be omitted:

class Person(var firstName: String, var lastName: String)

create an instance of a class

New instances of classes are created without the new keyword. You can think of them as being like function calls:

val f = Foo()

val p = Person(“Bill”, “Panner”)

kotlin vs Java

With the exception of the names of the getter and setter functions, if you’re coming to Kotlin from Java, this Kotlin code:

class Person(var firstName: String, var lastName: String)

is the equivalent of this Java code:

public class Person {

private String firstName; private String lastName;

public Person(String firstName, String lastName) { this.firstName = firstName;

this.lastName = lastName;

}

public String getFirstName() { return this.firstName;

}

public void setFirstName(String firstName) { this.firstName = firstName;

}

public String getLastName() { return this.lastName;

}

public void setLastName(String lastName) { this.lastName = lastName;

}

}

Constructor parameter visibility

Class constructor parameters are defined in the class header:

class Person(var firstName: String, var lastName: String)

class Person(val firstName: String, val lastName: String)

  var means fields can be read-from and written-to (they are mutable); they have both a getter and a setter. val

means the fields are read-only (they are immutable).

Accessing constructor parameters

Given this definition with var fields:

class Person(var firstName: String, var lastName: String)

you can create a new Person instance like this:

val p = Person(“Bill”, “Panner”)

You access the firstName and lastName fields like this:

println(“${p.firstName} ${p.lastName}”) Bill Panner

The REPL shows that the fields can be updated:

class Person(var firstName: String, var lastName: String)

val p = Person(“Bill”, “Panner”)

p.firstName = “William”

p.lastName = “Bernheim”

println(“${p.firstName} ${p.lastName}”) William Bernheim

  val fields are read-only

Had the fields been defined as val :

class Person(val firstName: String, val lastName: String)

val p = Person(“Bill”, “Panner”)

// can access the fields

println(p.firstName) Bill

println(p.lastName) Panner

// can’t mutate the fields

p.firstName = “William” error: val cannot be reassigned p.firstName = “William”


p.lastName = “Bernheim” error: val cannot be reassigned p.lastName = “Bernheim”

class Person(val firstName: String, val lastName: String)

you can still access them (via a getter method), but you can’t change their values (there is no setter method):

Summary:

  val fields are read-only

  var fields are read-write

tip: If you use Kotlin to write OOP code, create your fields as var fields so you can easily mutate them. If you prefer an Functional Programming style you may prefer Kotlin’s data classes.

visibility modifiers

“If the constructor has annotations or visibility modifiers, the constructor keyword is required, and the modifiers go before it”:

class Customer public @Inject constructor(name: String) { … }

Visibility modifiers are:

private protected internal public

“classes, objects, interfaces, constructors, functions, properties and their setters can have visibility modifiers.”

Here’s an example of internal :

// `internal` is visible everywhere in the same “module”

// see https://kotlinlang.org/docs/reference/visibility-modifiers.html

class TabAdapter internal constructor(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {…

Imports and Packages

Import and package statements are very similar to Java, with just a few additions/improvements.

Packages:

Package statements are just like Java, but they don’t have to match the directory the file is in Import statements:

  • There is no import static syntax
  • You can rename a class when you import it

The import statement is not restricted to only importing class You can also import:

  • Top-level functions and properties
  • Functions and properties declared in object declarations Enum constants
  • Finally, a collection of classes and functions are imported for you by default, such as kotlin.*

Package statements

Put package statements at the top of a file:

package foo.bar.baz

// the rest of your code here …

The only real difference with Java is that the package name doesn’t have to match the name of the directory that the file is in.

Because a Kotlin file doesn’t have to contain a class, it’s perfectly legal to put one or more functions in a file:

package foo.bar

fun plus1(i: Int) = i + 1 fun double(i: Int) = i * 2

Because of the package name, you can now refer to the function  plus1  in the rest of your code as   foo.bar.plus1 . Or as you’ll see in the import examples that follow, you can import the function into the scope of your other code like this:

import foo.bar.plus1

Import statements

Import statements work just like Java, with only a few differences:

There is no import static syntax

You can rename a class when you import it

The import statement is not restricted to only importing class

Kotlin doesn’t have a separate import static syntax. Just use a regular import declaration to import static methods and fields:

>>> import java.lang.Math.PI

>>> PI 3.141592653589793

>>> import java.lang.Math.pow

>>> pow(2.0, 2.0)

4.0

To avoid namespace collisions you can rename a class when you import it:

import java.util.HashMap as JavaHashMap

The REPL shows how it works:

>>> import java.util.HashMap as JavaHashMap

>>> val map = JavaHashMap<String, String>();

>>> map.put(“first_name”, “Alvin”) null

>>> map

{first_name=Alvin}

Here’s a combination of the two techniques just shown, (a) importing a static field and (b) renaming it during the import process:

import java.lang.Integer.MAX_VALUE as MAX_INT import java.lang.Long.MAX_VALUE as MAX_LONG

Here are the values in the REPL:

>>> MAX_INT 2147483647

>>> MAX_LONG 9223372036854775807

In addition to importing classes, you can also import:

Top-level functions and properties

Functions and properties declared in object declarations Enum constants

Default imports

When you first start working with Kotlin it can be a surprise that you can use the println function without having to write System.out.println every time. This is partly due to the fact that a collection of packages are imported into every Kotlin file by default:

kotlin.* kotlin.annotation.* kotlin.collections.*

kotlin.comparisons.* (since 1.1) kotlin.io.*

kotlin.ranges.* kotlin.sequences.* kotlin.text.*

The println function is declared in the kotlin.io package, and it’s automatically made available to you. When working with the Java Virtual Machine (JVM), these packages are also automatically imported:

java.lang.* kotlin.jvm.*

When you’re compiling Kotlin code to JavaScript this package is imported by default:

kotlin.js.*

Leave a Reply

Your email address will not be published. Required fields are marked *