Kotlin从入门到放弃之基础篇(四)
属性和字段
属性声明
在Kotlin中我们使用var关键字声明可变属性,或者用val关键字声明只读属性。
public class Person{
var name:String ="小明"
var age: Int = 18
val gender:String="男"
}
我们可以像Java中那样可以通过名称直接使用一个属性
public class printPerson{
var person = Person()
print("name=${person.name}")
}
Getters and Setters
声明一个属性的完整语法如下:
var <propertyName>: <PropertyType> [=<property_initializer>]
[<getter>]
[<setter>]
其中initializer,getter和setter都是可选的。其中var关键字修饰的属性是允许有getter和setter方法的,但是val关键字修饰的属性是final类型的不允许有setter方法。
另外,能够从成员函数或者初始化语句中推断出属性的类型,那么在属性声明的时候是可以忽略PropertyType的。
备用字段
在Kotlin中不可以有字段。然而当使用自定义访问器的时候需要备用字段,所以Kotlin使用field关键字提供了自动备用字段。
var counter=0
set(value){
if(value>=0) filed = value
}
♣ field关键字只能用于属性的访问器
编译器会检查访问器的代码,如果使用了备用字段(或者访问器是默认的实现逻辑),就会自动生成备用字段,否则就不会。
备用属性
如果备用字段不合适的话可以试试备用属性。备用属性隐式的对属性值的初始化声明避免空指针
private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
get() {
if (_table == null)
_table = HashMap()
return _table ?: throw AssertionError("Setto null by another thread")
}
编译时常量
那些在编译时就知道具体值的属性可以使用const关键字标记为编译时常量。该属性需要满足以下条件:
♣ 顶层或对象的成员
♣ 使用基本类型进行初始化
♣ 不能有自定义的getter方法
该属性可以被当作注解使用:
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"@Deprected(SUBSYSTEM_DEPRECATED) fun foo() { ... }
延迟初始化属性
那些拥有非空类型的属性,需要在构造器中进行初始化,但是有时构造器并不能满足所有需求。如果我们希望延迟属性初始化的时间,就可以用到lateinit关键字。
public class Person{
lateinit var student : Stuent
}
这个修饰符只能用在被var关键字修饰的属性中,不能用在构造方法中。并且,该属性不能有自定义的getter和setter访问器。这个属性必须是非空的,同时,也不能是一个基本类型
接口
接口的定义
Kotlin中的接口很想Java8。可以包含抽象方法和方法的实现,但是接口不能保存状态,意味着接口中的属性必须是抽象的,或者提供访问器的实现方式。
interface DoSomething{
fun run()//没有方法体
fun swim(){
//有方法体
}
}
接口的实现
一个类可以实现多个接口
class Person : DoSomething{
fun run(){
print("this is run")
}
}
接口中的属性
接口中可以存在抽象的属性,但是可以提供访问器的实现。接口中的属性不能有备用字段。
interface DoSomething{
val person : Person //默认为abstract
}
关于重写冲突
在之前的章节中有详细的讨论,不再赘述