引言
在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等。
总结
本大节次要介绍了面向对象的基本知识和类委托、属性委托等