This is the 11th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021

preface

In the last article, I mainly explained Kotlin’s knowledge about sets. In this article, I will explain Kotlin’s objects in detail.

Object 1.

1.1 Example 1 (No constructor)

class Player {
	// Analysis point 1
    var name = "abc"
        get() = field.capitalize()
        set(value) {
            field = value.trim()
        }
    var age = 10  
        get() = field.absoluteValue
        private set(value) { 
            field = value.absoluteValue
        }
    val rolledValue
    	// take a random number
        get() = (1 until 6).shuffled().first()

    var words: String? = null // Analysis point 2

    fun saySomeThine(a) { 
    	// Analysis point 3words? .also {"Hello ${it.toUpperCase()}" }.run(::println)
    }
}
fun main{
    var player = Player()
    player.name = "tom"
    // Player. age=-10 // Set was changed to private
    player.words="main hello" 
    println(player.name)
    println(player.age)
    println(player.rolledValue)
    player.saySomeThine()
}
Copy the code

Defines an object with corresponding member attributes. Note the analysis points:

  • Analysis point 1: The correspondingGet and set methods, and in the corresponding method to achieve the corresponding logic.
  • Analysis point 2: The member variable does not have anyGet and set methods
  • Analysis point 3: In the methodsaySomeThineIs used for member attributes.alsoKeyword, print last

Operation effect:

Tom
10
4
main hello
Copy the code

If a member of an object does not implement the corresponding GET and set methods and does not use private, it can still call the corresponding GET and set methods externally.

1.2 Example 2 (with primary constructor)

// ---------------- initializes
class Player1(
    _name: String,
    _age: Int,
    _isNormal: Boolean) {
    var name = _name
        get() = field.toLowerCase()
        private set(value) {
            field = value.trim()
        }
    private var age = _age
    var isNormal = _isNormal

    fun playerInfo(a) {
    	//println(_name) // error
        println("name: $name; age:$age; isNormal$isNormal")}}fun main(a) {
    var player = Player1("Tom".20.true)
    player.playerInfo()

}
Copy the code

Running effect

name: tom; age:20 ; isNormaltrue
Copy the code

From this code, this Player1 should be an object with a constructor that takes arguments. The corresponding _name, _age, and _isNormal are the construction parameters in the corresponding constructor, and the validity period is only in the corresponding constructor.

1.3 Example 3 (With primary and secondary constructors)

class Player2(
    _name: String,
    var age: Int = 12.// Execute in sequence 1
    var isNormal: Boolean) {
    var name = _name // Execute in sequence 2
        get() = field.capitalize()
        private set(value) {
            field = value.trim()
        }
    fun playerInfo(a) {
        println("name: $name; age:$age; isNormal$isNormal")}// This () executes the primary constructor equivalent to order 1 and 2
    constructor(name: String) : this(name, age = 100, isNormal = false ) {
        this.name = name.toUpperCase()
        println("constructor----------")
        // Execute in sequence 4
    }
    init { // Execute in sequence 3
        // The initialization code block is executed when the class instance is constructed
        // The value can be checked here and an exception will be thrown if the condition is met
        println("init----------")
        require(age > 10) { println("age must be positive") }
        require(name.isNotBlank()) { println("player must have a name")}}}fun main(a) {
    var player2=Player2("Tom".20.true)
    player2.playerInfo()
    var player3 = Player2("bob", isNormal = false)
    player3.playerInfo()
    var player4=Player2("hqk")
    player4.playerInfo()
}
Copy the code

Operation effect:

init---------- name: Tom; age:15 ; isNormaltrueinit---------- name: Bob; age:12 ; isNormalfalseinit---------- constructor---------- name: HQK; age:100 ; isNormalfalse
Copy the code

This time we add constructor and init to the code. Constructor means to create a subconstructor; Init is the equivalent of a static code block in Java. The corresponding order of execution is clearly marked in the comments.

The init block contains the require method, which means that an error will be reported if the expression is not true /false. The custom error message is implemented in the closure.

1.4 Example 4 (Delayed Initialization)

class Player3 {
    lateinit var equipment: String
    fun ready(a) {
        equipment = "sharp knife"
    }

    fun battle(a) {
        if (::equipment.isInitialized) println(equipment)
    }
}

fun main{
    var palyer3 = Player3()
    palyer3.ready()   // This method must be called to use the corresponding attribute variable
    palyer3.battle()
}
Copy the code

Operation effect:

sharp knife
Copy the code

And we learned from the previous study that when we define a variable, we either start with an initial value, or we do it by.? Indicates that this variable is nullable. But in the case of objects, I don’t want to assign an initial value and I don’t want the variable to be nullable, so it’s only lateInit that indicates that the property variable needs to be initialized later (before using it)!

What if it isn’t initialized before you use it? A null pointer is an exception. Kotlin offers a solution: you can perform an isInitialized check whenever you can’t confirm that the lateinit variable isInitialized

1.5 Example 5 (Lazy Initialization)


class Player4(_name: String) {
    var name = _name
    val config by lazy { loadConfig() }
    private fun loadConfig(a): Boolean {
        println("loading...")
        return false}}fun main{
    var play4 = Player4("Tom");
    println(play4.config)
}
Copy the code

Running effect

loading...
false
Copy the code

Here we see that config implements lazy initialization using by lazy {} when defining member attributes. When the play4.config member property is used, it initializes the corresponding action.

1.6 Example 6 (Initializing traps)

class Player5() {
    init {
    	// This will result in an error
        blood  = this.blood.times(4)}var blood = 100
}
Copy the code

When we put variables behind the init closure, we will find that the code has reported a syntax error. The solution is as simple as putting the init closure last.

class Player6() {
    var blood = 100
    init {
    	// So there is no error
        blood  = this.blood.times(4)}}fun main{
   var play6=Player6()
   println(play6.blood )
}
Copy the code

Operation effect:

400
Copy the code

1.7 Example 7 (Object Inheritance)

class Player7() {
    val name: String

    private fun firstLetter(a) = name[0]

    init {
        name = "Jack" // Analysis point 1
        firstLetter()
    }
    / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- inheritance -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
    open class Product(val name: String) {	// Analysis point 2
       open fun description(a) = "Product: $name"
        open fun load(a) = "Nothing..."
         fun add(num1: Int, num2: Int) = num1 + num2 // This method cannot be overridden by subclasses
    }
    class LuxuryProduct : Product("Java") {
        / / - overloading
        override fun load(a) = "Java " + description()
    }
}
/** * Type conversion */
fun sale(p: Player7.Product) {
    println(p.load())
}

fun main(a) {
    val play7 = Player7()
    println(play7.name)

	val product = LuxuryProduct()
    product.description().run(::println)
    product.load().run(::println)
    // Type detection
    println(product is LuxuryProduct)
    println(product is Player7.Product)

    sale(product)
    sale(product as Player7.Product) // Analysis point 3
}
Copy the code

Let’s start with these points:

  • Analysis point 1: As in the previous example, when the init code block is below the corresponding property definition, the corresponding variable can be initialized in this closure, even if the variable is usedvalModified, can still be initialized.
  • Analysis point 2: When we want to use inheritance, we can passopen class XXXDefines an inherited object whose methods can be used if you want to override the quilt objectopen Modify the corresponding method.A subclass inherits its parent class with the syntax:Class Subclass: parent class
  • Analysis point 3: This is used when we want to convert objectsasKeyword strong to corresponding object.

Running effect

Jack
Product: Java
Java Product: Java
true
true
Java Product: Java
Java Product: Java
Copy the code

conclusion

Well, this is the end of this article, this is thinking about the object in this article, but found that the content is too rich. There are many, many more, plus time doesn’t allow, and I have to write that code to masturbate, so I’ll leave it to the next one.