Note: the current document is a summary of Kotlin’s self-study, if there is any ambiguous meaning, please advise, thank you: -).
Directories: - Constructors - objects - Anonymous objects - Object declarations - Semantic differences between object expressions and object declarations - Modifiers - Keywords - delegates - Class delegates - Attribute delegates - Requirements - Latencies - Observer patterns - Attribute mappings - Local delegatesCopy the code
Constructor –A primary constructor has multiple subconstructions. all arguments to the primary constructor have default values
-
Main construct :(after class declaration)
Class ClazzName public constructor{} class ClazzName public @inject constructor(val/var params1: Type = defultValue){//constructor = public; //constructor = public;}}Copy the code
-
Secondary constructs: delegate or indirectly delegate to the main constructs, requiring the this keyword (or the constructor prefix)
Class Person(val name: String) {constructor(name: String, parent: Person) : This (name) {// add parameter or reassign name //... . }}Copy the code
-
Create a generic instance – without the new keyword
Val invoice = invoice () val customer = customer ("Joe Smith"Copy the code
object
The usual way objects are created is by passing constructor parameters.
1. Anonymous objects
General use of anonymous objects
Window. AddMouseListener (object: MouseAdapter() {override fun mouseClicked(e: MouseEvent) {//... }})Copy the code
Multiple anonymous objects that inherit or implement and need to be passed as parameters
Open class A(x: Int) {public open val y: Int = x} interface B {... } val ab: A = object : A(1), B { override val y = 15 }Copy the code
Anonymous object creation without inheritance or implementation
fun foo() {
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
Copy the code
A public function that returns an anonymous object of type Any cannot access its members.
Class C {// Private function, so its return type is anonymous object type private fun foo() = object {val x: String = "x"} // Public function, so its return type is Any fun publicFoo() = object {val x: String = "x"} fun bar() {val x1 = foo().x // no problem val x2 = publicFoo().Copy the code
Object statement
Object declarations can only be in other object declarations or non-inner classes.
Object DataProviderManager: Parent() {fun registerDataProvider(provider: DataProvider) {//... } val allDataProviders: Collection<DataProvider> get() = //... } / / direct call DataProviderManager. RegisterDataProvider (...).Copy the code
Semantic differences between object expressions and object declarations
There is an important semantic difference between object expressions and object declarations:
- Object expressions are executed immediately (and initialized) where they are used - object declarations are initialized lazily when first accessed - associated objects are initialized when the corresponding class is loaded (parsed), matching the semantics of Java static initializersCopy the code
The modifier
-
Val and var
Val read-only; Var creates getters and setters by default. Val creates a getter by default.Copy the code
-
Visibility modifier
-
Internal → replace → default, which means that the member is visible only within the same module. More specifically, a module is a set of Kotlin files compiled together:
An IntelliJ IDEA module; A Maven or Gradle project; A < kotlinc > Ant task executes a compiled set of files.Copy the code
-
Local variables, functions, and classes cannot have visibility modifiers.
-
The keyword
-
this
-
In a class member, this refers to the current object of the class.
-
In extension functions or function literals with receivers, this represents the receiver argument passed to the left of “.”.
Class A {// implicit tag @a inner class B {// implicit tag @b fun int.foo () {// Implicit tag @foo val A = this@A // this val B = this@B // B this val c = this // foo() receiver, an Int val c1 = this@foo // foo() receiver, A Int val funLit = lambda@fun String.() {val d = this // funLit2 receiver} val funLit2 = {s: String -> // the recipient of foo() because it contains lambda expressions // There is no recipient val d1 = this}}}}Copy the code
-
-
The abstract abstract
-
Companion → static companion object
-
Class has no static methods. In most cases, it recommends simply using package-level functions.
-
If you need to access a function inside another class, you can write it as a member of an object declaration within that class.
Class MyClass {companion object Factory {//Factory name can be omitted fun create(): MyClass = MyClass()}} // other classes call val instance = myclass.create () // val x = myclass.panionCopy the code
-
-
Const compile-time constant
See kotlin-3. Md for compile-time constantsCopy the code
-
Lateinit Delays the initialization of the property
-
Use fields to avoid compilation spacetime checking
-
This parameter can be used only with VAR
-
The attribute type cannot be empty or primitive
-
This can be initialized in the @setup function of the unit test;
-
Accessing a property before initialization throws an “accessed and not initialized” exception.
public class MyTest { lateinit var subject: testsubject@setup fun SetUp () {subject = TestSubject()} @test fun Test () {subject.method()}}Copy the code
-
entrust
Commissioned by class
Format:
class A{ fun aa() fun bb() ... } class A1:A{ override fun aa(){... } override fun bb(){... }... } class ClazzName(a:A):A by a{ ... } clazzName(A1()).aa()Copy the code
A class delegate calls all public functions that it does not have but that exist in the base class of the class annotation using the delegate parameter by, in the form of an inherited format.
How it works: The BY statement stores the delegate object internally, and the compiler generates methods for all annotation base classes that are forwarded to that object.
interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() { print(x) } } class Derived(b: Base) : Base by b //Base for BaseImpl b fun main(args: Array<String>) {val b = BaseImpl(10) Derived(b).print()Copy the code
Entrusted property
Delegate a getter or setter for a property to a function or operator of a class, using the **by keyword.
Attribute delegate requirements
For a read-only property (that is, declared by val), the delegate must provide a function called getValue that takes the following arguments:
ThisRef — must be the same as the property owner type (for extended properties — the extended type) or its supertype, property — must be type KProperty<*> or its supertype, this function must return the same type (or its subtype) as the property.
For a mutable property (that is, declared by var), the delegate must provide an additional function called setValue that takes the following arguments:
ThisRef — same as getValue(), property — same as getValue(), new Value — must be of the same type as the property or its supertype. The getValue() or/and setValue() functions can be provided by member functions of the delegate class or by extension functions. The latter is more convenient when you need to delegate properties to objects that do not originally provide these functions. Both functions need to be marked with the operator keyword.
A delegate class can implement either ReadOnlyProperty or ReadWriteProperty interfaces that contain the required operator methods. These two interfaces are declared in the Kotlin library:
interface ReadOnlyProperty<in R, out T> {
operator fun getValue(thisRef: R, property: KProperty<*>): T
}
interface ReadWriteProperty<in R, T> {
operator fun getValue(thisRef: R, property: KProperty<*>): T
operator fun setValue(thisRef: R, property: KProperty<*>, value: T)
}
Copy the code
delayed
Lazy () is a function that takes a lambda and returns an instance of lazy, which can be used as a delegate to implement the delay property. The first call to get() executes the LAMda expression passed to lazy() and records the result, and subsequent calls to get() simply return the result of the record.
Delay is thread safe with synchronous lock, by defaultLazyThreadSafetyMode.PUBLICATION
The incominglazy()
, the use ofLazyThreadSafetyMode.NONE
Pattern, which does not have any thread-safety guarantees and associated overhead.
val lazyValue: String by lazy { println("computed!" ) "Hello"} fun main(args: Array<String>) {println(lazyValue) println(lazyValue)} // Output content //computed! //Hello //HelloCopy the code
Delegate observer pattern
Delegates. Observables () and Delegates. Vetoable ()
Delegates. Observable () receives two parameters: initial value and handler when modified. This handler is called whenever we assign a value to the property (executed after the assignment). It takes three parameters: the assigned property, the old value, and the new value;
import kotlin.properties.Delegates class User { var name: String by Delegates. Observable ("<no name>") {// If... Println ("$old -> $new")}} Fun main(args: Array<String>) {val user = user () user.name = "first" user.name = "second"} secondCopy the code
Delegates. Vetoable () can intercept an assignment and “veto” it, invoking the handler passed to vetoable before the attribute is assigned a new value to effect.
Attribute Store to Map – Stores attribute values in a map.
class User(val map: Map<String, Any? >) { val name: String by map val age: Int by map } val user = User(mapOf( "name" to "John Doe", "age" to 25 )) println(user.name) // Prints "John Doe" println(user.age) // Prints 25Copy the code
val -> Map, var -> MutableMap
Local delegate click here
This article is from Kotlin Language Center