Kotlin series five --- data class, sealed class, inner class

Overview: I have been studying kotlin for a while, and I will spend a little time every day to look at it briefly. After watching it, I will forget it soon. Once again, it is proved that it is just a matter of sorting out. In this film, we will sort out the basic ones. The use of classes is relatively simple and generally similar to the things on the kotlin website.

data class

Whether in java or other languages, for the clarity of code logic, we always create some classes that are only used to save state attributes or data. These classes are called data classes. In kotlin, data classes are used for simpler and standardized use. , add its own flag and modifier data to the data class, and have its own rules, then we create a simple data class:
data class DataClass(var  name : String) {

}
To ensure consistent and meaningful behavior of the generated code, data classes must meet the following requirements:
  • The primary constructor needs to have at least one parameter;
  • All parameters of the primary constructor need to be marked as val or var;
  • Data classes cannot be abstract, open, sealed or internal;
  • (Prior to 1.1) Data classes can only implement interfaces.
Create an object of the data class and get its properties:
var data = DataClass("NAME")
println(data)
println(data.name)
Print property result:
02-07 09:50:05.995 3256-3256/? I/System.out: DataClass(name=NAME)
02-07 09:50:05.995 3256-3256/? I/System.out: NAME
Kotlin defines a constant standard for the creation of data classes. The restricted standard must be to achieve some common functions. When creating each data class, the compiler automatically exports the following members from all properties declared in the primary constructor:
  • equals()/hashCode() 对;
  • toString() format is "DataClass(name=NAME)";
  • The componentN() function corresponds to all properties in the order of declaration;
  • copy() function
The toString() method is the same as the output data above, and the property acquisition has also been used above. Let's print the equals and hasCode methods:
Log.e("=====", data.hashCode().toString())
Log.e("=====", data.equals(data.copy(name = "Change")).toString())
Here we introduce the attributes of copy separately. Copy literally copies a certain attribute, but kotlin's copy allows users to modify attributes, or is called incomplete copying, which produces a difference that an attribute is not necessarily the same. Object, its internal methods can be described as:
fun copy(name: String = this.name) =DataClass  (name)    
Now we copy the data object and change its name:
println(data.copy(name = "Change"))
println(data)
Output result:
02-07 10:01:04.454 4444-4444/? I/System.out: DataClass(name=Change)
02-07 10:01:04.454 4444-4444/? I/System.out: DataClass(name=NAME)
Destruction declaration
Destruction declaration: As the name implies, each parameter of the constructor is decomposed, and the object is created. The data created above is: var data = ...., now use the destructor to create
var (name) = DataClass("A")//The name here can be used directly
Log.e("======",name)
02-07 10: 08: 17.444 5393-5393 /? AND / ======: A

Sealed

Sealed classes are used to represent a restricted class inheritance structure: when a value is of a type in a finite set and cannot have any other type. In a sense, they are extensions of enum classes: the set of values ​​of an enum type is also limited, but only one instance of each enum constant exists, whereas a subclass of a sealed class can have as many states as it can contain. instance.
To declare a sealed class, add the sealed modifier before the class name. Although sealed classes can also have subclasses, all subclasses must be declared in the same file as the sealed class itself. (Prior to Kotlin 1.1, the rule was stricter: subclasses must be nested inside sealed class declarations).
Create a sealed class and its subclasses:
sealed class Parent

data class ChildFirst(var name: String) : Parent()

data class ChildSecond(var name: String):Parent()

data class ChildThird(var name: String):Parent()
  • A sealed class is itself abstract, it cannot be instantiated directly and can have abstract members.
  • A sealed class is not allowed to have a non-private constructor (its constructor defaults to private).
  • Note that classes that extend subclasses of sealed classes (indirect inheritors) can be placed anywhere without needing to be in the same file.
  • The key benefit of using sealed classes is that when using when expressions, if you can verify that the statement covers all cases, you don't need to add an else clause to the statement. Of course, this only works if you use when as an expression (using the result) and not as a statement.
fun getName(parent: Parent) : String? = when (parent){
is ChildFirst -> parent.name
is ChildSecond -> parent.name
is ChildThird -> parent.name
}

inner class

Kotlin allows a class to be nested inside a class, but the class at this time is different from java. The two classes are independent of each other in a sense, and the inner nested class cannot use external data:
data class DataClass(var name: String) {
    
    class Data {
        fun print() {
            Log.e("===========", "DataClass.Data")
        }
    }

}

DataClass.Data().print()//02-07 10:23:40.106 6569-6569/? E/===========: DataClass.Data
Although the nested class at this time is inside a tired, it is not a nested class, because the inner class in kotlin needs a special modifier: inner, now we modify the above nested class:
var age: Int = 20

inner class Data {
     fun print() {
         Log.e("===========",age.toString())
     }
}
The calling method at this time is also different from the previous one, and the object of the external class is called:
data.Data().print()
02-07 10:26:33.767 6909-6909/com.example.administrator.kotlinpractise E/============: 20//External class data output
anonymous inner class
Use object expressions to create anonymous inner class instances, we will use Rxjava more, we will create an anonymous object of observers:
Observable.just(1).subscribe(object : Observer<Int>{
    override fun onSubscribe(d: Disposable) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun onNext(t: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun onComplete() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun onError(e: Throwable) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

})
Use object: T to create an anonymous inner class of T, let's create a commonly used ClickListener for setting click events:
air_view.setOnClickListener(object : View.OnClickListener{
    override fun onClick(v: View?) {
        println("Click")
    }

}
In kotlin if an object is an instance of a functional Java interface (i.e. a Java interface with a single abstract method), you can create it using a lambda expression prefixed with the interface type:
air_view.setOnClickListener{  println("Click")}
The creation and use of these three classes are briefly introduced here. As long as you know the form and meaning of their use, you can use them flexibly as needed.


Guess you like

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