About the author: CSDN blog expert, Huawei cloud · cloud sharing expert certification
Series column: Kotlin beginner
Learning and communication: three people must have my teacher; Choose the good and follow it, and change the bad.
catalogue
2.1 defining extension functions
2.1. 4 define the superclass (Any) extension function
2.1. 5 generic extension function
4, Controllable class extension
5.3 rename extension (import file alias)
6, () - > unit and reference type ()->Unit
1, Introduction
Kotlin can extend the properties and functions of a class without inheriting or using the Decorator pattern.
Extension is a static behavior that does not affect the extended class code itself.
2, Extension function
Extension functions can add new functions to existing classes without modifying the original class.
2.1 defining extension functions
Extensions can be used for custom classes, such as List, String, and other classes in the Kotlin standard library. Similar to inheritance, extension can also share class behavior. When you can't contact a class definition or a class doesn't use the open modifier, so you can't inherit it, extension is the best choice to add class functions.
//Defines the extension function of the School class fun School.student():String{ return "$name-Learning knowledge" }
-
School: represents the receiver of the function, that is, the object of the function extension
-
student: name of extension function
-
String: return type ("$name - learn knowledge")
Others are similar to defining general functions.
2.1. 1. Define the School class
class School(var name:String){ //Self contained function fun teacher():String{ return "$name-Teaching and educating people" } }
2.1. 2 extension function
//Defines the extension function of the School class fun School.student():String{ return "$name-Learning knowledge" } //Defines the extension function of the String class fun String.addSC():String{ return "$this-Shuai Ci" } fun main() { //Original function of School class println(School("Super Seminary").teacher())//Super seminary - teaching and educating people //Extension function of School class println(School("Super Seminary").student())//Super seminary - learning knowledge //Extension function of String class println("Kotlin".addSC())//Kotlin shuaizi }
2.1. 3. Extended function support range
After the extension function is defined, it can be called directly under the same package, and the defined extension function needs to be imported under other packages. The extension functions defined under the extension package are used in the classkotlin package.
Extension functions with the same name cannot be defined in the same package.
import com.scc.kotlin.primary.extension.School import com.scc.kotlin.primary.extension.addSC import com.scc.kotlin.primary.extension.student fun main() { println(School("Class Bao Xia").student())//Class package - learning knowledge println("ClassKotlin".addSC())//ClassKotlin Shuai Ci }
Define the extension function addSC() under multiple packages. When calling:
2.1. 4 define the superclass (Any) extension function
Because Any is a superclass, its extension function can also be used directly by other classes. This function is really powerful.
//Define Any extension function fun Any.eat(): Any { return this } fun main() { //Because Any is a superclass, its extension function can also be used directly by other classes println("Superclass".eat())//Superclass println(15.eat())//15 }
Superclass eat().addSC() error
//An error is reported because the addSC() function is an extension function of the String class, and the Any class cannot be called directly //Unless "superclass" is used The return type of eat() Any is changed to String and then called. "Superclass".eat().addSC()
It's time to introduce generic extension functions.
2.1. 5 generic extension function
The new generic extension function can not only support any type of receiver, but also retain the type information of the receiver. After using generic types, the extension function can support more types of receivers and has a wider scope of application.
//Defining generic extension functions fun <T> T.scww():T{ return this } fun main() { //WaKa calls the generic extension function scww(), returns the String type, and calls the String type extension function addSC() println("WaKa".scww().addSC())//WaKa shuaizi //Int type 15 calls the generic extension function scww(), and returns int type to call the apply {} function println(15.scww().apply { })//15 }
-
String type WaKa calls the generic extension function scww(), returns string type and calls the string type extension function addSC()
-
Int type 15 calls the generic extension function scww(), and returns int type to call the apply {} function
Generic extension functions can be seen everywhere in the Kotlin standard library, such as the apply function. The apply function is defined as a generic extension function, so it can support any type.
public inline fun <T> T.apply(block: T.() -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block() return this }
3, Extended properties
In addition to adding function extension functions to classes, you can also define extension properties for classes.
Extended attributes can be defined in classes or kotlin files, but not in functions. Initialization property is not allowed to be initialized because it has no back-end field. It can only be defined by explicitly provided getters / setters.
Extended properties can only be declared as val.
//Define extended properties //Add an extended attribute to the String class, which can count the character length and add 10. val String.lengthSc get() = this.length.plus(10) //Add a position attribute to the School class val School.position get() = "${name}-Senior high school" fun main() { println("One, two, three, four, five, go up the mountain to fight the tiger".lengthSc)//21 println(School("Xinguan middle school").position)//Xinguan middle school - Senior High School }
4, Controllable class extension
You can also define extension functions for nullable types. By defining extension functions on nullable types, you can directly solve the possible null value problem in the extension function body.
//Nullable class extension //When String is null, print all blank - default fun String?.nullWithDefault(default: String) { println(this ?: "are void-$default") } //When School is null, print default - the School is gone fun School?.dropOut(default: String) { println(this ?: "$default-The school is gone") } fun main() { var str: String? = null str.nullWithDefault("empty")//Everything is empty - empty str = "Data has arrived" str.nullWithDefault("empty")//Data has arrived var school: School? = null school.dropOut("No name")//No name. - the school is gone school = School("Shuaici College") school.dropOut("Default drop out")//com.scc.kotlin.primary.extension.School@19dfb72a }
infix keyword
The infix keyword is applicable to extensions and class functions with a single parameter. It allows you to call functions in a more concise syntax. If a function definition uses the infix keyword, the point operation between the receiver and the function and a pair of parentheses of the parameter can be omitted when calling it. (similar to the to function)
//infix keyword infix fun String?.nullInfixDefault(default: String){ println(this ?: "Infix-$default") } fun main() { str = null str nullInfixDefault "Null value" //Infix null str = "Not empty" str nullInfixDefault "Null value" //Not empty //This is similar to mapOf mapOf("Key" to "Value") }
to function source code
Generic extension function, prefixed with infix keyword
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
Extension functions in the Kotlin standard library: many functions provided by the Kotlin standard library are realized through extension functions and extension attributes. Standard library files containing class extensions are usually named after the class name plus the s suffix, such as sequences kt,Ranges.kt,Maps.kt.
5, Define extension file
The extension function needs to be used in multiple files. It can be defined in a separate file and then import ed.
5.1 definition extension file
package com.scc.kotlin.primary.extension //Define extension file fun <T> T.scFile(): T { println("come from ScFile Greetings from") return this }
5.2 use
scFile() is called for files under the same package name:
fun main() { str.scFile()//Greetings from ScFile }
scFile() is called for files under other packages:
import com.scc.kotlin.primary.extension.scFile fun main() { var userInfo4 = UserInfo4() userInfo4.scFile()//Greetings from ScFile }
5.3 rename extension (import file alias)
import com.scc.kotlin.primary.extension.scFile as scAliasFile fun main() { var userInfo4 = UserInfo4() userInfo4.scAliasFile()//Greetings from ScFile using the newly defined alias // userInfo4.scFile() / / unable to use. An error is reported }
6, () - > unit and reference type ()->Unit
package com.scc.kotlin.primary.extension //() - > Unit: ordinary anonymous function fun String.doAnonymous(anonymous:() -> Unit):String{ anonymous() return "$this,AnonymousN" } //String. () - > Unit: this in the anonymous function points to a string object, which is called implicitly fun String.doAnonymousString(anonymous: String.() -> Unit) :String{ println(this) anonymous() return this } //The generic anonymous function used here uses its internal this fun <T> T.doAnonymousT(anonymous: T.() -> Unit):T { println(this) anonymous() return this } fun main() { //Ordinary anonymous function "a".doAnonymous{ //println("$this, check") / / if this is used here, an error will be reported } //this inside the anonymous function points to a String object "b".doAnonymousString{ println("$this,have a look") } 15.doAnonymousT { println("$this,How lonely invincible is") } }
DSL
Using this programming paradigm, you can write the industry-famous "domain specific language" (DSL), an API programming paradigm, which exposes the functions and characteristics of the receiver, so that you can use the lambda expressions you define to read and configure them.