Extension functions of the Kotlin series

Brief description: Today is the fifth bullet of the Kotlin Talking Series. This talk mainly talks about using the extension function feature in Kotlin to make our code simpler and cleaner. The extension function is a unique new feature in the Kotlin language. Using it can reduce a lot of boilerplate code and greatly improve the efficiency of development; in addition, the use of the extension function is also very simple. I will explain extension functions in Kotlin from the following aspects.

  • 1. Why use extension functions in Kotlin?
  • 2. How to use extension functions and extension properties?
  • 3. What are extension functions and properties?
  • 4. Difference between extension function and member function
  • 5. Extension functions cannot be overridden

1. Why use extension functions in Kotlin

We all know that the Koltin language has very good interoperability with Java, so the new feature of extension functions can be smoothly integrated with existing Java code. Even pure Kotlin projects can be built based on Java libraries, even some framework libraries in Android, third-party libraries. Extension functions are very suitable for the mixed development model of Kotlin and Java languages. In many companies, some relatively stable and good libraries are written in Java, and there is no need to rewrite them in Kotlin language. But if you want to extend the interface and functionality of the library, extension functions may come in handy. Another advantage of using Kotlin's extension functions is that they have no side effects and will not affect the original library code or functionality. Let's take a look at what the extension function looks like

  • A simple example of setting bold for TextView
//扩展函数定义
fun TextView.isBold() = this.apply { 
    paint.isFakeBoldText = true
}

//扩展函数调用
activity.find<TextView>(R.id.course_comment_tv_score).isBold()

2. How to use extension functions and extension properties

  • 1. Basic use of extension functions

Just put the extended class or interface name before the function name to be added. This class or name is called the receiver type , and the name of the class and the function are connected with a "." call. this refers to the receiver object , which can access the methods and properties accessible to the extended class.

Note: The receiver type is defined by the extension function, and the receiver object is the object instance of the receiver type, then the object instance can access the member methods and properties in this class, so the extension function is generally regarded as a member function to use.

  • 2. Basic use of extended properties
    Extended properties are actually just a way to access properties, and these extended properties do not have any state, because it is impossible to add additional property fields to objects in existing Java libraries, just use The concise syntax is similar to directly manipulating properties, but it is actually method access.
//扩展属性定义
var TextView.isBolder: Boolean
    get() {//必须定义get()方法,因为不能在现有对象添加字段,也自然就没有了默认的get()实现
        return this.paint.isFakeBoldText
    }
    set(value) {
        this.paint.isFakeBoldText = true
    }
//扩展属性调用
activity.find<TextView>(R.id.course_comment_tv_score).isBolder = true

Note:
* The extension attribute is similar to the extension function definition. It also has a receiver type and a receiver object. The receiver object is also an instance of the receiver type. Generally, it can be used as a member attribute in a class.

  • The get() method must be defined. In Kotlin, the properties in the class are all added with the get() method by default, but since the extended property does not add additional properties to the classes in the existing library, there is no default get() method. realization. So the get() method has to be added manually.

  • Since the set() method is overridden, it means that the access permissions of this property are readable and writable, and you need to use var

3. What are extension functions and properties

We can see from the above example that the extension function of kotlin is really powerful, and it can add properties and methods to the classes of the original library without any side effects. properties and functions. With such a powerful function, what is the principle behind it? In fact, it is very simple. You can see at a glance the corresponding Java code after decompile through decompile.

  • 1. Substantial principle of extension function

The extension function is actually a static function corresponding to Java. The static function parameter is an object of the receiver type, and then you can use this object to access the member properties and methods in this class, and finally return an object of this receiver type. itself. This externally feels the same as using a class's member functions.

public final class ExtendsionTextViewKt {//这个类名就是顶层文件名+“Kt”后缀,这个知识上篇博客有详细介绍
   @NotNull
   public static final TextView isBold(@NotNull TextView $receiver) {//扩展函数isBold对应实际上是Java中的静态函数,并且传入一个接收者类型对象作为参数
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      $receiver.getPaint().setFakeBoldText(true);//设置加粗
      return $receiver;//最后返回这个接收者对象自身,以致于我们在Kotlin中完全可以使用this替代接收者对象或者直接不写。
   }
}
  • 2. Calling the extension function defined in Kotlin in Java

After analyzing the principle of extension functions in Kotlin, we also know very well how to call the extension functions defined in Kotlin in Java. Similar, but the only difference is that you need to pass in a receiver object parameter.

ExtendsionTextViewKt.isBold(activity.findViewById(R.id.course_comment_tv_score));//直接调用静态函数
  • 3. Substantial principle of extended attribute

The extended attribute is actually the set and get methods that provide access to a certain attribute. These two set and get methods are static functions, and both pass in an object of the receiver type, and then use this object instance to access and modify it internally. Properties of the class to which the object corresponds.

public final class ExtendsionTextViewKt {
   //get()方法所对应生成静态函数,并且传入一个接收者类型对象作为参数
   public static final boolean isBolder(@NotNull TextView $receiver) {
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      return $receiver.getPaint().isFakeBoldText();
   }
   //set()方法所对应生成静态函数,并且传入一个接收者类型对象作为参数和一个需要set的参数
   public static final void setBolder(@NotNull TextView $receiver, boolean value) {
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      $receiver.getPaint().setFakeBoldText(true);
   }
}
  • 4. Calling the extension properties defined in Kotlin in Java

It is also very simple for Java to call the extension properties defined in Kotlin, which is equivalent to directly calling the generated set() and get() methods.

    ExtendsionTextViewKt.setBolder(activity.findViewById(R.id.course_comment_tv_score), true);

Fourth, the difference between extension functions and member functions

When it comes to the difference between extension functions and member functions, we have already made it clear through the above examples. Here is a summary:

  • 1. Extension functions and member functions are used in a similar way, and can directly access the methods and properties of the extended class. (Principle: An object of the extended class is passed in, and the instance object is actually used internally to access the methods and properties of the extended class)
  • 2. Extension functions cannot break the encapsulation of extended classes, and cannot directly access internal private functions and properties like member functions. (Principle: The principle is very simple. The extension function access is actually the object access of the class. Since the object instance of the class cannot access the internal private functions and properties, the natural extension function cannot access the internal private functions and properties)
  • 3. The extension function is actually a static function that is outside the class, while the member function is the internal function of the class.
  • 4. Parent class member functions can be overridden by subclasses, but extension functions cannot

5. Extension functions cannot be overridden

In Kotlin and Java, we all know that the member functions of a class can be overridden, and the subclass can override the member function of the parent class, but the subclass cannot override the extension function of the parent class.

open class Animal {
    open fun shout() = println("animal is shout")//定义成员函数
}

class Cat: Animal() {
    override fun shout() {
        println("Cat is shout")//子类重写父类成员函数
    }
}

//定义子类和父类扩展函数
fun Animal.eat() = println("Animal eat something")

fun Cat.eat()= println("Cat eat fish")

//测试
fun main(args: Array<String>) {
    val animal: Animal = Cat()
    println("成员函数测试: ${animal.shout()}")
    println("扩展函数测试: ${animal.eat()}")
}

operation result:

The above operation results once again show that the extension function is not a part of the class, it is declared outside the class, although the subclass and the superclass have the same extension function, but the extension function is actually a static function. From the internal perspective of compilation, the subclass and the parent class have the same extension function. In fact, two static extension functions with the same name are defined to pass in the parent class object and the subclass object respectively, so the method called must also be in the parent class. methods and methods in subclasses, so the output must be of the parent class.

Guess you like

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