KotLin 相关文档
官方在线Reference
kotlin-docs.pdf
Kotlin for android Developers 中文翻译
Kotlin开发工具集成,相关平台支持指南
Kotlin开源项目与Libraries
Kotlin开源项目、资源、书籍及课程搜索平台
Google’s sample projects written in Kotlin
Kotlin and Android
Constructors
下面的代码示例了:
使用constructor,声明构造函数;
init { } 初始化语句块;
//import kotlin.reflect.jvm.internal.impl.javax.inject.Inject
/**
* desc :
* author: stone
* email : aa86799@163.com
* time : 31/05/2017 15 44
*/
class Person1 constructor(firstName: String) {}//主构造函数可以直接定义在类名后
class Person2 constructor(val firstName: String) { }
class Person3 constructor(var firstName: String) { }
class Person4(firstName: String) { } //如果主构造函数没有任何注解或可见性修饰符,构造函数关键字可以省略
class Person5(name: String) {//若主构造函数中,不进行初始化, 可放在init{}中
val name: String
init {
println("initialize")
this.name = name
}
}
class Person6(name: String) {//主构造函数中的参数初始化,也可以用在成员属性上
val name = String
// val name: String = name
}
//如果主构造函数前有可见性修饰符或注解,就一定需要加上constructor 关键字
class Person7 private/* @Inject*/ constructor(name:String, age: Int)
/*
当有其它构造函数,依赖主构造函数,形如 constructor(...) : this(...)
对于 主构造函数中的参数,如上所说,要么放在init{} ,要么以赋值给成员属性
对于 非主构造函数中的参数,在定义属性时,则就需要一个默认值了
注意:init{} 要定义在 属性定义后, 否则会访问不到
*/
class Person8(val name: String) {
var pName: String = name
var pAge: Int = 0 //默认值
init {
pName = name
}
constructor(name: String, age: Int) : this(name) {
pAge = age
}
}
//其实所有主构造函数中的参数,都会被自动赋上一个默认值, 所以也可以手动指定一个默认值
private class Person9(val name: String = "")
/*
class 中可以有:
— Constructors and initializer blocks
— Functions
— Properties
— Nested and Inner Classes
— Object Declarations
*/
fun main(args: Array<String>) {
val per9 = Person9("stone")
TT(3)
TT(3, 4)
}
class TT {//没有在类名后定义主构造函数
constructor(a: Int)
constructor(a: Int, b:Int) : this(a)
}
inheritance
下面的代码示例了:
使用open, 表示可类被继承,表示函数、属性可被重写;
使用override 表示重写 函数、属性;
kotlin不能声明static的方法和属性;
abstract 声明抽象类与方法
package com.stone.clazzobj.inheritance
/**
* desc : 类的继承,方法重写
* author: stone
* email : aa86799@163.com
* time : 31/05/2017 16 32
*/
open class Base1 //使用open后 表示可被继承
class Derived1 constructor() : Base1() //继承时,用 : 表示继承关系,且需要表明父类的主构造函数
open class Base2(name: String)
class Derived2(fName: String) : Base2(fName)
//子类没有主构造函数,在内部其它构造函数,使用super 调用父类构造函数
open class Base3(name: String)
class Derived3 : Base3 {
constructor(name: String) : super(name)
}
open class Base4 {
open fun v() {}
fun nv() {}
}
class Derived4() : Base4() {
final override fun v() {} //final 后 不可被再重写
// override fun nv() {} //非open的fun 不能被重写
}
open class Foo1 {
open val x: Int get() {return 1 + 3}
/*open var x: Int get() {return x} set(value) {x = value}*/
/*
当声明了属性的get()后,就不会再自动生成对应的set方法了
val 声明的属性 是不会有 set方法的, 因其不可变
属性要被子类重写,也需声明时 加上 open
*/
}
class Bar1 : Foo1() {
override var x: Int = 9
}
/*
如果有多个超类、接口,且它们定义了相同的成员,子类在重写时:
使用super<superClass/superInterface> 前缀 来标识
*/
open class A {
open fun f() { print("A") } fun a() { print("a") }
}
interface B {
fun f() { print("B") } // interface members are 'open' by default
fun b() { print("b") }
}
class C() : A(), B {
// The compiler requires f() to be overridden:
override fun f() {
super<A>.f() // call to A.f()
super<B>.f() // call to B.f()
}
}
open class AbsBase {
open fun f() {}
}
abstract class AbsDerived: AbsBase() {
// override fun f() {} //直接重写
override abstract fun f() //抽象重写,还是需要子类重写
}
class StableDerived : AbsDerived() {
override fun f() {
}
}
/*
Kt中不能声明static的方法和属性
*/
fun main(args: Array<String>) {
val d3 = Derived3("stone")
val f1 = Foo1()
println(f1.x)
// f1.x = 1 //
val b1 = Bar1()
println(", ${b1.x}")
}
Properties
下面代码示例了:
const定义常量属性;
var定义的属性,可以重写get/set;
val定义的属性,仅能重写get;
field 关键字;
lateinit 定义延迟初始化的属性;
package com.stone.clazzobj.propertiesfields
//import kotlin.reflect.jvm.internal.impl.javax.inject.Inject
/**
* desc :
* author: stone
* email : aa86799@163.com
* time : 01/06/2017 10 21
*/
//常量 必须定义在 Kotlin文件顶级, 不能定在 class或其它内部(在内部就是二级了)
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { }
class PropertiesOperation(size: Int) {
val size = size
//var 可变,可重写 get()、set() 仅指定get()时,需要进行初始化,指定默认值; set()为默认实现
var stringRepresentation1: String = ""
get() = this.toString()
//var 重写 get()、set()
var stringRepresentation2: String
get() = this.toString()
set(value) {
setDataFromString(value) // parses the string and assigns values to other properties
}
private fun setDataFromString(value: String) {}
//val 不可变,只能重写 get()
val isEmpty1: Boolean get() = this.size == 0
val isEmpty2 get() = this.size == 0 // has type Boolean
var setterVisibility: String = "abc"
private set // the setter is private and has the default implementation
var setterWithAnnotation: Any? = null
/*@Inject*/ set // annotate the setter with Inject
/*
使用 field 关键字,指代它所在的属性。它仅能在 属性的 get或set中使用
还有个比较形象的称呼:backing field。 向后看,就知它是指哪个属性了
*/
var counter = 0 // the initializer value is written directly to the backing field
set(value) {
if (value >= 0) field = value
}
/*
backing property
使用一个私有属性 来实现当前属性的get、set
*/
private var _table: Map<String, Int>? = null
val table: Map<String, Int>
get() {
if (_table == null) {
_table = HashMap() // Type parameters are inferred }
return _table ?: throw AssertionError("Set to null by another thread")
}
return _table ?: throw AssertionError("Set to null by another thread")
}
}
object Tes {//singleton
//针对var 属性, 延迟初始化
lateinit var str: String
fun init(arg: String) {
str = arg
}
//针对val 属性, 延迟加载
val name: String by lazy {
println("load name")
"stone86"
}
}
fun main(args: Array<String>) {
val gs = PropertiesOperation(3)
// gs.setterVisibility = "" //set是private的 无法访问
Tes.init("stone")
println(Tes.str)
println(Tes.name)
}
这里给出一个自定义View继承View时的实现