introduction
In Kotlin, I can declare ordinary classes, data classes and static classes. It also has abstract classes and interfaces. The abstract keyword can only act on ordinary classes.
Classes and objects
General class
Ordinary classes in Kotlin are defined through the class keyword. By default, these classes are of final type and cannot be inherited. If you want to be inherited, you need to add the open keyword in front
class Person(var id:Int?) { //id can be null var name:String? = null constructor():this(999) //Heavy load cosntructor(id:Int, name:String):this(id) { //Heavy load this.name = name } } fun main() { var ps1= Person() var ps2 = Person(20) }
abstract class
Define an abstract class through abstract class. The default is open class
abstract class BaseActivity {}\
Interface
The definition of interface is very similar to java
interface UserApi {}
Static class
object StudentManager{ fun show() { //Note that this is a singleton method // .. } @JvmStatic //Adding this keyword is the static method fun show2(){ // .. } }
Inner class
Static inner class
class A { object Instance { var instance = A() } compannion object { //Static method of A fun getInstance() : A = Instance.instance } } // A.getInstance()
General internal class
class A { inner class Class2 { } class Class3 { //Note that this is not an inner class } }
extend
class User(val name:String) fun User.print() { print("user name: $name") } fun main() { var user = User() user.print() }
Kotlin extension can add functions without modifying the original class, which will not be affected. The code is not really added, and the extended content does not participate in polymorphism. It is what is called. However, if the extension of the subclass overrides the extension of the parent class, the extension function of the subclass will be used if the subclass is used to call the function. In short, whoever invokes it will use whoever's extension.
Property can also be extended. Property initialization can only be realized through getter/setter
Of course, you can also extend the associated objects to achieve staticization
entrust
Class delegate
Class delegate and proxy patterns are very similar. From the perspective of java, class a implements a public interface or directly inherits from B, and then holds a class B object internally. Then, the method of class B can be used in class A.
Kotlin can easily do this
interface Base { fun print() } class BaseImpl(val x:Int): Base{ override fun print() { println(x) } } class Driver(b:Base) : Base by b fun main() { var driver = BaseImpl(10) Driver(driver).print() }
As can be seen from the above code, the print of the Driver here is entrusted to the BaseImpl implementation
Attribute delegate
val/var [attribute name]: [type] by [expression]
The expression refers to the principal-agent class, and the get and set of this property will be handed over to the getValue and setValue implementation of this class.
class Example{ var p : String by Delegate() } //Delegate class class Delegate { operator fun getValue(thisRef: Any?, property: KProperty): String { return "$thisRef, It's entrusted here ${property.name} attribute" } operator fun setValue(thisRef: Any?, property: KProperty, value: String) { println("$thisRef of ${property.name} Property is assigned to $value") } } fun main(args: Array) { val e = Example() println(e.p) //Access the property and call the getValue() function e.p = "Runoob" //Call the setValue() function println(e.p) }
The output result is:
Example@433c675d , the p attribute is delegated here
Example@433c675d The p attribute of is assigned Runoob
Example@433c675d , the p attribute is delegated here
Attribute lazy loading:
var lazyValue:String by lazy{ // loading property }
When this attribute is used for the first time, it will call the content in the lazy{} code block and cache it in memory. The second time, it will get the value directly from memory.
Attribute recorder
class User{ var name:String by Delegates.observable("Initial value"){ prop, old, new -> Log.d("old:$old, new:$new") } } fun main(){ val user = User() user.name = "1" user.name = "2" }
When the above main starts executing, output:
old: initial value, new:1
old:1,new:2
Attribute Map mapper
class Site(val map:Map){ val name:String by map val url:String by map } fun main(){ var site = Site(mapOf( "name" to "Baidu" "url" to "http://www.baidu.com" )) print(site.name) //Baidu print(site.url) // http://www.baidu.com }
In other words, we only need to construct a class similar to the map structure, and kotlin will automatically help resolve and set the attribute to the object.
If the attribute is var, you need to replace the Map with MutabbleMap
class Site(val map:MutabbleMap){ val name:String by map val url:String by map } fun main(){ var site = Site(mutableMapOf( "name" to "Baidu" "url" to "http://www.baidu.com" )) print(site.name) //Baidu print(site.url) // http://www.baidu.com }
Function type delegate
fun example(computeFoo: () -> Foo) { val memoizedFoo by lazy(computeFoo) if (someCondition && memoizedFoo.isValid()) { memoizedFoo.doSomething() } }
Where () - > Foo is a function type, that is, a function that returns Foo, similar to
interface A{ void Foo();}, It's equivalent to passing new A.
The memoizedFoo is then delegated to computeFoo for execution.
Kotlin and Java intermodulation
Kotlin can support writing functions directly without writing classes, while Java calls kotlin and needs to write the file name Kt Function name is enough.
When Java and Kotlin call each other, Kotlin calls java code, has more writing methods, and supports closures, lombda, etc.
summary
This section mainly introduces the basic knowledge of object-oriented, class delegation, attribute delegation, etc