Kotlin classes and objects


Release date:2023-09-22 Update date:2023-10-13 Editor:admin View counts:309

Label:

Kotlin classes and objects

Class definition

Kotlin classes can contain constructors and initialization code blocks, functions, attributes, inner classes, and object declarations.

Kotlin use keywords in class declare the class, followed by the class name:

class Runoob {  // Class name is Runoob
    // Within the braces are class body constructions
}

We can also define an empty class:

class Empty

You can define member functions in a class:

class Runoob() {
    fun foo() { print("Foo") } // member function
}

Properties of the class

Attribute definition

The properties of the class can use the keyword var declared as mutable, otherwise use read-only keywords val declared immutable.

class Runoob {
    var name: String = ……
    var url: String = ……
    var city: String = ……
}

We can use the constructor to create an instance of the class as we would with a normal function:

val site = Runoob() // There is no new keyword in Kotlin

To use an attribute, simply refer to it by name

site.name           // Use Number to reference
site.url

Kotlin class in can have a primary constructor, as well as one or moresecondary constructors, which are part of the class header, after the classname:

class Person constructor(firstName: String) {}

If the main constructor does not have any comments and no visibility modifiers, then constructor keywords can be omitted.

class Person(firstName: String) {
}

Getter and setter

The complete syntax of the property declaration:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

getter and setter are all optional.

If the attribute type can be inferred from the initialization statement or the member function of the class, the type can be omitted val setting is not allowed setter function because it is read-only.

var allByDefault: Int? // Error: requires an initialization statement,
 default implementation of getter and setter methods
var initialized = 1    // Type is Int, default implementation of getters and setters
val simple: Int?       // Type is Int, default implementation getter,
 but must be initialized in the constructor
val inferredType = 1   // The type is Int, and the default implementation is getter

Example

The following example defines a Person class that contains two variable variables, lastName and no . lastName modifies the ‘getter’ methoand no modifies the setter method

class Person {

    var lastName: String = "zhang"
        get() = field.toUpperCase()   // Convert variables to uppercase after assignment
        set

    var no: Int = 100
        get() = field                // Backend variable
        set(value) {
            if (value < 10) {       // If the passed in value is less than 10,
 return this value
                field = value
            } else {
                field = -1         // If the value passed in is greater
 than or equal to 10, return -1
            }
        }

    var heiht: Float = 145.4f
        private set
}

// test
fun main(args: Array<String>) {
    var person: Person = Person()

    person.lastName = "wang"

    println("lastName:${person.lastName}")

    person.no = 9
    println("no:${person.no}")

    person.no = 20
    println("no:${person.no}")

}

The output is as follows:

lastName:WANG
no:9
no:-1

Kotlin class cannot have fields in. Provide Backing Fields (back-end variable) mechanism, alternate field use field keyword declaration field keywords can only be used for accessors of properties, such as the example above:

var no: Int = 100
        get() = field                // Backend variable
        set(value) {
            if (value < 10) {       // If the passed in value is less than 10, return this value
                field = value
            } else {
                field = -1         // If the value passed in is greater than or equal to 10, return -1
            }
        }

Non-empty properties must be initialized at the time of definition kotlin provides a scheme that can delay initialization, using the lateinit keyword description properties:

public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // dereference directly
    }
}

Main constructor

The main constructor cannot contain any code, the initialization code can beplaced in the initialization code segment, and the initialization code snippet can be used init keyword as a prefix.

class Person constructor(firstName: String) {
    init {
        println("FirstName is $firstName")
    }
}

Note: the parameters of the main constructor can be used in the initialization code snippet or in the property initialization code defined by the class body n. A concise syntax that uses the main constructor to define properties and initialize property values (which can be var or val ):

class People(val firstName: String, val lastName: String) {
    //...
}

If the constructor has comments or visibility modifiers, then constructor keyword is required, and comments and modifiers should be placed before it.

Example

Create a Runoob class and pass in the site name through the constructor:

class Runoob  constructor(name: String) {  // Class name is Runoob
    // Within the braces are class body constructions
    var url: String = "http://www.runoob.com"
    var country: String = "CN"
    var siteName = name

    init {
        println("Initialize website name: ${name}")
    }

    fun printTest() {
        println("I am a function of a class")
    }
}

fun main(args: Array<String>) {
    val runoob =  Runoob("Novice Tutorial")
    println(runoob.siteName)
    println(runoob.url)
    println(runoob.country)
    runoob.printTest()
}

The output is as follows:

Initialize website name: Novice Tutorial
Novice Tutorial
http://www.runoob.com
CN
I am a function of a class

Secondary constructor

Class can also have a secondary constructor that needs to be prefixed constructor :

class Person {
    constructor(parent: Person) {
        parent.children.add(this)
    }
}

If the class has a primary constructor, each secondary constructor will represent the primary constructor, either directly or indirectly through another secondary constructor. To proxy another constructor in the same class to use the this keywords:

class Person(val name: String) {
    constructor (name: String, age:Int) : this(name) {
        // initialization...
    }
}

If a non-abstract class does not declare a constructor (primary or secondaryconstructor), it produces a constructor with no arguments. The constructor is public . If you don’t want your class to have a public constructor, you have to declare an empty main constructor:

class DontCreateMe private constructor () {
}

Note: in JVM the virtual machine, if all parameters of the main constructor have default values, the compiler generates an additional no-parameter constructor, which directly uses the default value. This makes it possible Kotlin . It can be easier to use things like Jackson or JPA uses a no-parameter constructor to create a library of class instances.

class Customer(val customerName: String = "")

Example

class Runoob  constructor(name: String) {  // Class name is Runoob
    // Within the braces are class body constructions
    var url: String = "http://www.runoob.com"
    var country: String = "CN"
    var siteName = name

    init {
        println("Initialize website name: ${name}")
    }
    // Secondary constructor
    constructor (name: String, alexa: Int) : this(name) {
        println("Alexa ranking $alexa")
    }

    fun printTest() {
        println("I am a function of a class")
    }
}

fun main(args: Array<String>) {
    val runoob =  Runoob("Novice Tutorial", 10000)
    println(runoob.siteName)
    println(runoob.url)
    println(runoob.country)
    runoob.printTest()
}

The output is as follows:

Initialize website name: Novice Tutorial
Alexa Ranked 10000
Novice Tutorial
http://www.runoob.com
CN
I am a function of a class

Abstract class

Abstraction is one of the characteristics of object-oriented programming. The class itself, or some members of the class, can be declared as abstract . There is no concrete implementation of abstract members in the class.

Note: there is no need to label abstract classes or abstract members open notes.

open class Base {
    open fun f() {}
}

abstract class Derived : Base() {
    override abstract fun f()
}

Nested class

We can nest classes in other classes and look at the following examples:

class Outer {                  // External Class
    private val bar: Int = 1
    class Nested {             // Nested classes
        fun foo() = 2
    }
}

fun main(args: Array<String>) {
    val demo = Outer.Nested().foo() // Call Format: External Class,
 Nested Class, Nested Class Method/Attribute
    println(demo)    // == 2
}

Inner class

Inner class usage inner keyword to represent.

The inner class has a reference to the object of the external class, so the inner class can access the external class member properties and member functions.

class Outer {
    private val bar: Int = 1
    var v = "Member Properties"
    /**Nested Inner Class**/
    inner class Inner {
        fun foo() = bar  // Accessing External Class Members
        fun innerTest() {
            var o = this@Outer //Get member variables of external classes
            println("Internal classes can refer to members of external classes, such as:" + o.v)
        }
    }
}

fun main(args: Array<String>) {
    val demo = Outer().Inner().foo()
    println(demo) //   1
    val demo2 = Outer().Inner().innerTest()
    println(demo2)   // Internal classes can refer to members of external classes,
 such as member properties
}

To disambiguate, access the this we use the this@label , of which @label it’s a reference, this Label of the source.

Anonymous inner class

Use object expressions to create anonymous inner classes:

class Test {
    var v = "Member Properties"

    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}

/**
 * Define interfaces
 */
interface TestInterFace {
    fun test()
}

fun main(args: Array<String>) {
    var test = Test()

    /**
     * Using object expressions to create interface objects, that is,
 instances of anonymous inner classes.
     */
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("Object expression creates an instance of an anonymous inner class")
        }
    })
}

Class modifier

Class modifiers include classModifier and accessModifier :

  • classModifier class property modifiers that indicate the characteristicsof the class itself.

abstract//Abstract class
final//Class is not inheritable, default attribute
enum//Enumeration class
open//Class inheritable, class defaults to final
annotation//Annotation class
  • accessModifier: Access modifier

private//visible only in the same file
protected//Visible in the same file or subclass
public//Visible everywhere called
internal//Visible within the same module

Example

// file name:example.kt
package foo
private fun foo() {} // Visible within example.kt
public var bar: Int = 5 // This attribute is visible everywhere
internal val baz = 6    // Visible within the same module

Powered by TorCMS (https://github.com/bukun/TorCMS).