引言

在Kotlin中,我能够申明一般类、数据类、动态类,它也有抽象类和接口,其中abstract关键字只能作用在一般类。

类和对象

一般类

Kotlin中的一般类通过class关键字定义,这品种默认都是final类型的,无奈被继承。如果心愿被继承,须要在后面减少open关键字

class Person(var id:Int?) {  // id可为null  var name:String? = null  constructor():this(999)  // 重载  cosntructor(id:Int, name:String):this(id) {  // 重载    this.name = name  }}fun main() {  var ps1= Person()  var ps2 = Person(20)}

抽象类

通过abstract class定义一个抽象类,默认是open class

abstract class BaseActivity {}\

接口

接口的定义和java十分相似

interface UserApi {}

动态类

object StudentManager{   fun show() {  // 留神,这是单例办法      // ..   }   @JvmStatic  // 减少这个关键字才是static办法   fun show2(){      // ..   }}

外部类

动态外部类

class A {  object Instance {    var instance = A()  }  compannion object {    // A的静态方法    fun getInstance() : A = Instance.instance  }}// A.getInstance()

一般外部类

class A {  inner class Class2 {      }  class Class3 {    // 留神这个不是外部类  }}

扩大

class User(val name:String)fun User.print() {  print("用户名: $name")}fun main() {  var user = User()  user.print()}

Kotlin扩大能够在不批改原类的根底上减少性能,原类不受影响。没有真正减少代码,扩大的内容不参加多态,调用的哪个就是哪个。但如果子类的扩大笼罩了父类的扩大,如果用子类去调用该函数,会应用子类的扩大函数。总之,谁调用就应用谁的扩大。
属性也能够扩大,属性初始化只能通过getter/setter实现
当然也能够对伴生对象进行扩大,以实现动态化

委托

类委托

类委托和代理模式很相似,从java的角度看,就是类A实现一个公共接口或间接继承B,而后外部持有一个B类对象。进而可在A类中应用B类的办法。
Kotlin很容易实现上述形式

interface Base {  fun print()}class BaseImpl(val x:Int): Base{  override fun print() {    println(x)  }}class Driver(b:Base) : Base by bfun main() {  var driver = BaseImpl(10)  Driver(driver).print()}

从上述代码能够看出,这里的Driver的print委托给BaseImpl实现

属性委托

val/var [属性名]:[类型] by [表达式]
其中表达式指的是委托代理类,该属性的get和set会交给该类的getValue和setValue实现。

class Example{    var p : String by Delegate()}// 委托的类class Delegate {    operator fun getValue(thisRef: Any?, property: KProperty): String {        return "$thisRef, 这里委托了 ${property.name} 属性"    }    operator fun setValue(thisRef: Any?, property: KProperty, value: String) {        println("$thisRef 的 ${property.name} 属性赋值为 $value")    }}fun main(args: Array) {    val e = Example()    println(e.p)     // 拜访该属性,调用 getValue() 函数    e.p = "Runoob"   // 调用 setValue() 函数    println(e.p)}

输入后果为:
Example@433c675d, 这里委托了 p 属性
Example@433c675d 的 p 属性赋值为 Runoob
Example@433c675d, 这里委托了 p 属性

属性懒加载:

var lazyValue:String by lazy{    // loading property}

该属性第一次用到时会调用lazy{}代码块中的内容,并缓存到内存中,第二次就间接从内存中获取到值了。

属性记录器

class User{    var name:String by Delegates.observable("初始值"){        prop, old, new ->        Log.d("old:$old, new:$new")    }}fun main(){    val user = User()    user.name = "1"    user.name = "2"}

当上述main开始执行时,输入:
old:初始值,new:1
old:1,new:2

属性Map映射器

class Site(val map:Map){    val name:String by map    val url:String by map}fun main(){    var site = Site(mapOf(        "name" to "百度"        "url" to "http://www.baidu.com"    ))        print(site.name) // 百度    print(site.url) // http://www.baidu.com}

也就是说,咱们只需结构一个和map构造差不多的类,kotlin就会主动帮忙解析,并将属性设置该该对象。

如果属性为var,则须要把Map换成MutabbleMap

class Site(val map:MutabbleMap){    val name:String by map    val url:String by map}fun main(){    var site = Site(mutableMapOf(        "name" to "百度"        "url" to "http://www.baidu.com"    ))        print(site.name) // 百度    print(site.url) // http://www.baidu.com}

函数类型委托

fun example(computeFoo: () -> Foo) {    val memoizedFoo by lazy(computeFoo)    if (someCondition && memoizedFoo.isValid()) {        memoizedFoo.doSomething()    }}

其中 ()->Foo 是一个函数类型,也就是一个返回Foo的函数,相似于
interface A{ void Foo();},相当于传了new A。
而后memoizedFoo委托给computeFoo执行。

Kotlin和Java互调
Kotlin能够反对不写类间接写函数,而Java调用Kotlin这样的函数式,须要写文件名Kt.函数名即可。
Java和Kotlin互调时,Kotlin调用java代码,领有更多写法,反对闭包,lombda等。

总结

本大节次要介绍了面向对象的基本知识和类委托、属性委托等