Kotlin extends functions/attributes

In Kotlin, you can extend the functionality of a class whose code cannot be modified. For example, we can not modify the source code of the SDK, but we can add some functions by way of extension to expand the function of the SDK

– Extension function

Usage:

  1. Define two classes
/* open class FatherClass {} class ChildClass: FatherClass() { }Copy the code
  1. Add extension functions to both classes
fun FatherClass.className() = "father"
fun ChildClass.className() = "child"

fun FatherClass.printClassName(fatherClass: FatherClass) {
    println(" fatherClass  ${fatherClass.className()} ")
}

fun ChildClass.printChildClassName(childClass: ChildClass){
    println(" childClass  ${childClass.className()} ")
}
Copy the code
  1. Execute extension functions for both classes in the main method
    FatherClass().printClassName(FatherClass())
    FatherClass().printClassName(ChildClass())
    ChildClass().printClassName(FatherClass())
    ChildClass().printClassName(ChildClass())

    ChildClass().printChildClassName(ChildClass())
Copy the code
  1. The value printed out
 fatherClass  father 
 fatherClass  father 
 fatherClass  father 
 fatherClass  father 
 childClass  child 

Process finished with exit code 0
Copy the code
  1. If we call the extension printClassName of the parent class, we’ll print father as the className of both the parent class and the ChildClass

When a subclass calls its own extension function, the printed className is Child. This is because the extension function of a class cannot really modify the class it extends. It does not directly add a function to the class. It just defines a static method in the class where the extension function is declared and passes in the class object of the extension function. Let’s see what this code looks like when compiled into a Java file

import kotlin.Metadata; import kotlin.jvm.internal.Intrinsics; import org.jetbrains.annotations.NotNull; public final class TestMainKt { @NotNull public static final String className(@NotNull FatherClass $this$className) { Intrinsics.checkNotNullParameter($this$className, "$this$className"); return "father"; } @NotNull public static final String className(@NotNull ChildClass $this$className) { Intrinsics.checkNotNullParameter($this$className, "$this$className"); return "child"; } public static final void printClassName(@NotNull FatherClass $this$printClassName, @NotNull FatherClass fatherClass) { Intrinsics.checkNotNullParameter($this$printClassName, "$this$printClassName"); Intrinsics.checkNotNullParameter(fatherClass, "fatherClass"); String var2 = " fatherClass " + className(fatherClass) + ' '; boolean var3 = false; System.out.println(var2); } public static final void printChildClassName(@NotNull ChildClass $this$printChildClassName, @NotNull ChildClass childClass) { Intrinsics.checkNotNullParameter($this$printChildClassName, "$this$printChildClassName"); Intrinsics.checkNotNullParameter(childClass, "childClass"); String var2 = " childClass " + className(childClass) + ' '; boolean var3 = false; System.out.println(var2); } public static final void main(@NotNull String[] args) { Intrinsics.checkNotNullParameter(args, "args"); printClassName(new FatherClass(), new FatherClass()); printClassName(new FatherClass(), (FatherClass)(new ChildClass())); printClassName((FatherClass)(new ChildClass()), new FatherClass()); printClassName((FatherClass)(new ChildClass()), (FatherClass)(new ChildClass())); printChildClassName(new ChildClass(), new ChildClass()); }}Copy the code
  1. As you can see from the Java code snippet, we are calling only static methods in the current calling class TestMainKt in main, and when we pass in ChildClass, it is forcibly converted to FatherClass. That’s why when you call an extension function of a parent class, whether it’s a parent class or a child class, it prints father, okay
  2. How to call Kotlin’s extension function in Java
Funfile. printReadText(text: funfile. printReadText); String) {println(" printReadText \n $text")} Kotlin's main function is fun main(args: Array<String>) {val file = file (" ideaprojects.iml ") file.printreadtext (file.readtext ()) static void main(String[] args) { File file = new File("IdeaProjects.iml"); TestMainKt.printReadText(file, FilesKt.readText(file, Charsets.UTF_8)); }Copy the code
  1. As you can see, extension functions in Java are called from classes that declare extension functions. And it’s called directly by the point function. One thing to note is that when you call an extension function of a class in Java, the first argument is passed to the object of the class to be extended

– Extended attributes

Similar to extension functions, there are extension properties in Kotlin. Because the class extension does not insert the actual property or member variable into the class, extension properties cannot be initialized and can only be changed by get/set

– Other knowledge points:

  1. Companion objects can also be extended and declared by way of class.panion.funname (){}
  2. When extensions are used in different packages, they can be imported from the caller through import

Reference link: Extension