当前位置:网站首页>Kotlin advanced - class

Kotlin advanced - class

2022-06-25 09:52:00 seevc

This article belongs to Kotlin Advanced , The content related to class , Mainly involves :
Class definition 、 Class properties and functions 、 Class inheritance 、 Abstract classes and interfaces 、 Principal and agent 、 Single case 、 Data class 、 Companion 、 Operator overloading 、 Enumerating and sealing classes .

1、 Getting started with object orientation , Class creation

Example :

// Create a simple class , This class has two variables 
class HelloKotlin(var letter:String ,var letter2: String)

fun main() {
    var demo = HelloKotlin("Hello"," Kotlin")

    println("${demo.letter}${demo.letter2}")
}

2、 Define the properties and methods of a class

Access right : The default is public, Private properties or methods use private modification
Example :

package com.example.kotlin_demo
// Create a simple class , This class has two variables 
class HelloKotlin(var letter:String ,var letter2: String){
    /**
     *  Method definition 
     */
    fun method(){
        println(" I am defining a method ")
    }
}

fun main() {
    var demo = HelloKotlin("Hello"," Kotlin")
    println("${demo.letter}${demo.letter2}")
    demo.method()
}

3、 Class inheritance

Kotlin The middle class defaults to final type , Cannot be inherited , If you want to be inherited and overridden by methods, you must add keywords to the class or overridden methods open. The following example :

// Parent class ,
// Yes open modification : Allow other classes to inherit 
// nothing open modification : No other classes are allowed to inherit 
open class Parent {
    // A method in the parent class 
    // Yes open modification : Allow subclasses to override 
    // nothing open modification : Subclass override is not allowed 
    open fun action(){
        println("Parent action----------")
    }
}

//Child Class inherits from Parent class 
class Child : Parent() {
    // The subclass overrides the action Method 
    override fun action(){
        println("Child action----------")
    }
}

4、 Abstract classes and interfaces

Abstract classes use keywords abstract, The definition is as follows :

/**
 *  abstract class 
 */
abstract class AbstractDemo {
    // Define an abstract method 
    abstract fun absAction()
}

Interface uses keywords Interface, Examples are as follows :

/**
 *  Define an interface 
 */
interface InterfaceDemo {
    // There is no way to implement it 
    fun action()
    // Realized the method 
    fun action2(){
        println(" I am a action2.")
    }
}

The use of abstract classes and interfaces , Examples are as follows :

/**
 *  Inherited the abstract class AbstractDemo And interface InterfaceDemo
 */
class InheritDemo : AbstractDemo(),InterfaceDemo {
    // Implements abstract methods in abstract classes 
    override fun absAction() {
        println(" I come from abstract methods in abstract classes ")
    }

    // Implements the methods in the interface 
    override fun action() {
        println(" I come from the interface action Method ")
    }

    // Overriding the methods in the interface 
    override fun action2() {
        super.action2()
        println(" I come from the methods implemented in the interface ")
    }
}

notes :
1. Abstract classes and interfaces have been implicitly declared as open type , Allow other classes to inherit , So there is no need to show the declaration here open.
2. If a non abstract method in an abstract class wants its subclass to override , Need to add open identification .

5、Kotlin Agent and delegation are implemented in

Use keywords by To implement agency and delegation

1. The interface agent

For two classes that implement the same interface , The following example :
Interface class :

// An interface is defined 
interface IDelegate {
    fun delegateAction()
}

One implemented IDelegate Interface DelegateImp.kt class

// Inherited IDelegate Interface 
class DelegateImp1 : IDelegate {
    // The interface method is implemented 
    override fun delegateAction() {
        println(" I come from Child, The interface is implemented delegateAction Method ")
    }
}

Defines a class that implements the proxy interface , adopt by The implementation is delegated to DelegateImp1 Class implementation IDelegate Interface , as follows :

// Inherited IDelegate Interface , And entrust to Child Class implementation 
// Conditions of entrustment : Inherited from the same interface 
class ByDelegateImp : IDelegate by DelegateImp1() {

}
2. Property agent

Custom attribute proxy class :


import kotlin.reflect.KProperty
// Define a property proxy class 
class PropertyDelegate(var value:String) {
    // The property proxy must implement a getValue Method 
    operator fun getValue(any:Nothing?, property: KProperty<*>):String{
        return value
    }
    // The property proxy must implement a setValue Method 
    operator fun setValue(any:Nothing?, property:KProperty<*>, str:String){

    }
}

adopt by Use this property to proxy the class , as follows :

fun main() {
    // adopt by Using attribute proxies 
    var str : String by PropertyDelegate(" I am a proxy class ")
    println(str)
    str = "haha"
    println(str)
}

The final output is :

 I am a proxy class 
 I am a proxy class 
3. Common delegate attributes in the system

1. Delay properties (lazy properties): Its value is calculated only on the first access ;
lazy() Is to accept a lambda And return a Lazy Function of instance , The returned instance can be used as a delegate to implement the delay property : First call get() Will execute the passed to lazy() Of lambda Expression and record the result , Subsequent calls get() Just return the result of the record .

// Use lazy Delegate properties 
val lazyValue :String by lazy {
    println("computed!")
    "Hello"
}
println(lazyValue)

The output content is :
computed!
Hello

2. Observable properties (observable properties): The listener will be notified of this property change ;
Delegates.observable() Take two parameters : Initial value and modification time handler (handler). This handler is called whenever we assign a value to a property ( Execute... After assignment ). It has three parameters : Assigned property 、 Old value and new value :

class User {
    var name: String by Delegates.observable("<no name>") {
        prop, old, new ->
        println("$old -> $new")
    }
}

fun main() {
    val user = User()
    user.name = "first"
    user.name = "second"
}

The output value is :
-> first
first -> second

3. Store attributes in the map
A common use case is in a mapping (map) Store the value of the attribute in . This often occurs in things like parsing JSON Or do something else “ dynamic ” In the application of things . under these circumstances , You can use the mapping instance itself as a delegate to implement delegate properties .

class UserMap(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}

fun main() {
    val user = UserMap(mapOf(
            "name" to "John Doe",
            "age"  to 25
    ))

    println("name=${user.name},age=${user.age}")
}

Output is :
name=John Doe,age=25

System attribute delegation reference is from :kotlin- Delegates and attribute delegates

6、kotlin In a single case

object
stay Java There are classes with static methods in , Use static Keyword identification , stay kotlin There is no , but kotlin There are keywords in object, Use this keyword to identify the class , This is a single example , All methods in the class can be accessed directly through the class name , similar java Static methods in .

// By using object It is identified as a singleton 
object Singleton{
    fun log(str:String){
        println(str)
    }
}

fun main() {
    // Call the method directly through the class name , similar Java Static methods in 
    Singleton.log(" I am the one in the single case log Method .")
}

Output is :
I am the one in the single case log Method .

companion object Associated object declaration method
In general, methods in a class can only be accessed through class objects , But how can it be like java Just like the classes in, some methods are declared as static methods ? The answer is companion object, By using this declaration, you can call the method directly through the class name .
Generation time of associated objects :① The associated object function or property is called ;② Class instantiation .
Examples are as follows :

//Kotlin The methods declared in the class are non - static 
// But sometimes I want to define some methods as static , You can use companion object Keywords to identify 
class CompanionObjectDemo {
    companion object{
        fun log(string: String){
            println(" I come from the companion method ---${string}")
        }
    }

    fun other(str : String){
        println(str)
    }
}

fun main() {
    // Method to call companion object 
    CompanionObjectDemo.log("companion function")

    var demo = CompanionObjectDemo()
    // Call method in object 
    demo.other("other function")
}

Output is :
I come from the companion method —companion function
other function

7、Kotlin Data class in (data modification )

Kotlin A species peculiar to , Use keywords data To embellish .

  • The data class implements the superclass by default (Any) Of equals、hashCode、toString function .
  • Provides copy function , similar Java Of clone, The main constructor is executed when copying , If one of the variables is assigned in a secondary constructor , You can't copy To come over , The value needs to be set manually .
  • Support structural syntax , namely :val (x, y) = DataClassTest(10, 20) form

The defined data class needs to meet the following conditions :

  • There has to be Take at least one parameter Primary constructor for
  • Arguments to the main constructor It has to be for val perhaps var, Cannot be a temporary variable
  • Data classes cannot be used abstract、open、sealed and inner modification ;

Use scenarios
It is often necessary to compare 、 A class that copies or prints its own content .
Example :

data class DataClassTest(var x: Int, var y: Int) {
    val isInvalidate = x > 0 && y > 0
}

fun main() {
    println(DataClassTest(10, 5))
    //data The data class provides support for structure operations by default 
    val (x, y) = DataClassTest(10, 20)
}

Definition of deconstruction function in ordinary class
Define the way
operator fun component1() = x
operator fun component2() = y

operator componentN() = n
If the main constructor has several parameters, it will produce several corresponding component

/**
 *  Common classes support deconstruction definitions 
 */
class Coor(var x: Int, var y: Int) {
    operator fun component1() = x
    operator fun component2() = y

}
fun main() {
    println(DataClassTest(10, 5))

    // Common classes support deconstruction syntax 
    val (p,q) = Coor(10,20)
}

8、Kotlin Operator overloading in class

Kotlin Operator overloading is supported in , Common operator overloads are shown in the following table

The operator Function name effect
+plus Add one object to another
+=plusAssign Add one object to another , Then assign the result to the first object
-minus Subtract one object from another
==equals If two objects are equal , Then return to true, Otherwise return to false
>compareTo If the object on the left is larger than the object on the right , Then return to true, Otherwise return to false
[]get Returns the element at the specified location in the collection
rangeTo Create a range object
incontains If an object is contained in a collection , Then return to true

An example is as follows :

class OperatorTest(var x: Int, var y: Int) {
    /**
     *  Yes “+” Operator overloading 
     */
    operator fun plus(other: OperatorTest) = OperatorTest(x + other.x, y + other.y)

    /**
     *  Yes "-" Operator overloading 
     */
    operator fun minus(other: OperatorTest) = OperatorTest(x - other.x, y - other.y)
}

fun main() {
    val op1 = OperatorTest(10, 20)
    val op2 = OperatorTest(5, 30)
    println(op1 + op2)
    println(op1 - op2)
}

9、Kotlin Enumeration type in (enum) And sealing class (sealed)

1. enumeration

Follow java equally ,kotlin There are also enumeration types in , Same way of use , Examples are as follows :

// Define an enumeration type 
enum class EnumDemo {
     Monday , Tuesday , Wednesday , Thursday , Friday , Saturday , Sunday 
}

fun main() {
    // Output the index and value of enumeration type 
    for (item in EnumDemo.values()){
        println("ordinal--${item.ordinal},name--${item.name}")
    }
}

The output is :
ordinal–0,name– Monday
ordinal–1,name– Tuesday
ordinal–2,name– Wednesday
ordinal–3,name– Thursday
ordinal–4,name– Friday
ordinal–5,name– Saturday
ordinal–6,name– Sunday

2. Sealing class (sealed)

Sealing class , Similar enumeration , But sealed classes are mainly for classes , Sealed classes are used to represent restricted class inheritance structures : When a value is of a limited number of types 、 And there can be no other type of . It can be understood as an extension of enumeration type .
To declare a sealed class , You need to add before the class name sealed Modifier . Although sealed classes can also have subclasses , But all subclasses must be declared in the same file as the sealed class itself or nested inside the sealed class declaration . reason : use sealed The modified class is private Access type
Example :

// Mode one : Nested inside a sealed class 
sealed class SealedDemo {
    class Monday(var string: String) : SealedDemo(){
        fun mondayAct(){
            println("Monday--->${string}")
        }
    }
    class Tuesday(var string: String) : SealedDemo(){
        fun mondayAct(){
            println("Tuesday--->${string}")
        }
    }
}

fun main() {
    val monday = SealedDemo.Monday(" Monday ")
    val second = SealedDemo.Tuesday(" Tuesday ")
    monday.mondayAct()
    second.mondayAct()
}

Example 2 :

// Mode two : The sealed class is declared in the same file 
sealed class SealedDemo2
data class Const(val number: Double) : SealedDemo2()
data class Sum(val e1: SealedDemo2, val e2: SealedDemo2) : SealedDemo2()
object NotANumber : SealedDemo2()

fun main() {
    val const = Const(10.0)
    val sum = Sum(const,const)
}

Enum types vs. sealed classes

dimension enumeration Sealing class
keyword enumsealed
Statement Nested within a class Nested inside a class or declared in the same file
type Enumeration constants are all objects Sealed classes are for classes

Welcome to leave a message for us to exchange and learn from each other !


Sample source address kotlin_demo

原网站

版权声明
本文为[seevc]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202200547583022.html