Moving to Kotlin - enum classes and extensions

enum class

Enumeration classes in Kotlin are very similar to enumeration types in Java and have the characteristics of classes. An enumerable set of values ​​of the same type is generally defined as an enumeration class.

Basic usage

In Kotlin, enumeration types exist in the form of classes , so they are called enumeration classes. The following are examples:

enum class Color {
    RED, GREEN, BLUE
}

Everything in Kotlin is an object, so each enumeration type is also an object, and multiple enumeration types are separated by , .

Let's see how to use it:

var color: Color = Color.BLUE

var color2 = Color.GREEN

// 比较两个枚举类型变量
var bool: Boolean = color == color2

It should be noted that to refer to the value in the enumeration class, you need to add the enumeration class name. By default, the element value of the enumeration class is directly output, and the name of the element value is output.

Specify numeric values ​​for enumeration values

In fact, each value of the enumeration class is the object of the current enumeration class. Therefore, if you want to specify a number for the value of each enumeration class, you can directly pass it in through the constructor.

enum class Direction private constructor(var value: Int) {
    NORTH(1), WEST(2), EAST(3), SOUTH(4)
}

Other functions

First of all, it is necessary to specify a value for each enumeration value. This number does not necessarily start from 0, nor is it necessarily in order, so the position of the enumeration value in the enumeration class and the value corresponding to the enumeration value may be not the same.

Both Java and Kotlin provide corresponding APIs to get the name and index of enumeration values. Kotlin provides the name and ordinal properties, which are used to obtain the enumeration value name and index, respectively.

println(color.name) // 返回枚举的名字
println(color.ordinal) // 返回枚举的索引

In addition, you can also use the valueOf method to pass in the name of the enumeration value to get the value corresponding to the enumeration value.

expand

Extensions are a very important feature in Kotlin by which members can be added to a class without source code. In the case of team development, function modules can also be distributed to multiple people through expansion.

Extend native API

Although JDK and Kotlin provide rich APIs natively, these APIs still seem to be insufficient, and additional APIs need to be added to these libraries.

Extending system classes outside of classes, since the extended parts are put into their own source code, these source codes can still run on other machines' JDK and Kotlin runtimes. Kotlin can extend both the JDK API and Kotlin.

fun ArrayList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1]
    this[index1] = this[index2]
    this[index2] = tmp
}

The above code extends the native collection class ArrayList and extends the swap exchange method.

This code can be placed in any Kotlin file. Generally, it will be placed at the top level of the Kotlin file. Of course, it can also be placed in front of the swap method.

Extend custom class

There are many purposes of extending classes. In addition to the system classes that need to be extended, the classes we write also need to be extended. The method of extending custom classes is the same as extending system classes:

open class Parent(var value1: Int, var value2: Int) {
    var mVaule1 = value1
    var mValue2 = value2
    fun add(): Int {
        return mVaule1 + mValue2
    }
}

class Child(value1: Int, value2: Int) : Parent(value1, value2) {
    fun sub(): Int {
        return value1 - value2
    }
}

// 通过扩展向Parent类添加一个输出结果方法
fun Parent.printlnResult() {
    println("${value1}+${value2}=${add()}")
}

fun Child.printlnResult() {
    println("${value1}-${value2}=${sub()}")
}

Because the open boone is used in the top-level function, it is not possible to add inheritable member functions by extension (Kotlin does not allow inheritance by default).

Member function conflict resolution

If a member function added to a class by extension has exactly the same structure as the original member function in the class, which takes precedence?

The answer is: Inner member functions have higher precedence, therefore, inner member functions cannot be overridden by extension methods.

Extended properties

Extension properties are similar to extension methods. Kotlin properties must be initialized in the class, and the initialization needs to use the backing field, which is the field field. The value set by the property can be saved in the field, or the property value can be obtained from the field. However, there is no backing field for extended properties. Therefore, extended properties need to implement the setter part so that they can be initialized for extended properties.

class MClass {
    var mValue: Int = 0
    var str: String = ""
        get() = str
        set(value) {
            field = value
        }
}

// 属性扩展
var MClass.newVaule: Int
    get() = mValue
    set(value) {
        mValue = value
    }

Since the extended attribute attribute does not have a backing field field, a class member variable is required to save and obtain the attribute value. But member variables need to be declared as public, otherwise extended properties cannot be accessed.

Extended companion object

Companion Objects: Solve the awkwardness of not having static members in Kotlin classes.

If there is a companion object in the class, you can use extension to add members to the companion object.

class MClas {
    companion object {

    }
}

fun MClas.Companion.func() {
    println("伴随对象成员函数")
}

extended range

The extension code written above is in the same kotlin file in the same package. Of course, it is the same in different Kotlin files in the same package, but if it is in Kotlin in different packages, import the corresponding resources using import . The import guide package was introduced before, so it is no longer cumbersome.

extension in class

In fact, extensions can also be defined in classes.

class D {
    fun bar() {
        println("D.bar")
    }
}

class C {
    fun baz() {
        println("C.baz")
    }

    // 在类中对另一个类进行方法扩展
    fun D.foo() {
        bar()
        baz()
    }

    fun caller(d: D) {
        d.foo()
    }
}

Call a member function of a specific class

If A is extended in B, then the member function of both A and B is called in the extension method of A, which is called A or B? as follows:

class A {
    fun func() {
        println("A.func")
    }
}

class B {
    fun func() {
        println("B.func")
    }

    fun A.doo() {
        func() // 调用A类的func方法
        [email protected]() // 调用B类的func方法
    }

    fun call(a: A) {
        a.doo()
    }
}

If you call B's func function in A.doo, you need to use [email protected]() , and calling the method in class A can be used directly.

Inheritance of extended members

As mentioned before, extension members cannot be inherited, but this statement is inaccurate. A more accurate statement is: unloaded top-level extension members cannot be inherited, because the open keyword cannot be added. But in a class to extend another class can add the open keyword.

summary

Although enum classes don't appear very often in code, it's nice to define an enumerable set of related values, or at least make the code more readable (much better than using constants or just numbers). Extensions are supported in many languages, making full use of Kotlin extensions can make the code easier to maintain and also bring more flexibility.

For more exciting content, please pay attention to my WeChat public account - Android Motor Vehicles
write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325558277&siteId=291194637