前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android进阶】Kotlin面向对象

【Android进阶】Kotlin面向对象

原创
作者头像
易寒
发布2022-01-26 10:01:20
5090
发布2022-01-26 10:01:20
举报
文章被收录于专栏:Android知识

引言

在Kotlin中,我可以声明普通类、数据类、静态类,它也有抽象类和接口,其中abstract关键字只能作用在普通类。

类和对象

普通类

Kotlin中的普通类通过class关键字定义,这种类默认都是final类型的,无法被继承。如果希望被继承,需要在前面增加open关键字

代码语言:txt
复制
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

代码语言:txt
复制
abstract class BaseActivity {}\
接口

接口的定义和java非常类似

代码语言:txt
复制
interface UserApi {}
静态类
代码语言:txt
复制
object StudentManager{
   fun show() {  // 注意,这是单例方法
      // ..
   }

   @JvmStatic  // 增加这个关键字才是static方法
   fun show2(){
      // ..
   }
}
内部类

静态内部类

代码语言:txt
复制
class A {
  object Instance {
    var instance = A()
  }
  compannion object {    // A的静态方法
    fun getInstance() : A = Instance.instance
  }
}

// A.getInstance()
普通内部类
代码语言:txt
复制
class A {
  inner class Class2 {
    
  }

  class Class3 {
    // 注意这个不是内部类
  }
}

扩展

代码语言:txt
复制
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很容易实现上述方式

代码语言:txt
复制
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()
}

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

属性委托

val/var 属性名:类型 by 表达式

其中表达式指的是委托代理类,该属性的get和set会交给该类的getValue和setValue实现。

代码语言:txt
复制
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 属性

属性懒加载:
代码语言:txt
复制
var lazyValue:String by lazy{
    // loading property
}

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

属性记录器
代码语言:txt
复制
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映射器
代码语言:txt
复制
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

代码语言:txt
复制
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
}
函数类型委托
代码语言:txt
复制
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等。

总结

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 类和对象
    • 普通类
    • 抽象类
      • 接口
        • 静态类
          • 内部类
            • 普通内部类
            • 扩展
            • 委托
              • 类委托
                • 属性委托
                  • 属性懒加载:
                    • 属性记录器
                      • 属性Map映射器
                        • 函数类型委托
                        • 总结
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档