Kotlin类

类与对象

####基本构造

//使用class声明,默认为public
class Invoice{

}

//如果没有类体,可以忽略花括号
class Empty

//构造函数若没有任何注解或修饰符,则可以省略constructor关键字
class Person constructor(firstName : String){}

//若类需要初始化,需要放入init块中,不能放入构造函数中(阿里开发文档亦有此规范)
class Customer(name : String){
    init{
        logger.info("Customer initialized with value ${name}")
    }
}

//构造方法的参数可以在初始快中使用,也可以在类体内声明的属性初始化器中使用
class Customer(name : String ){
    val customerKey = name.toUpperCase()
}

//次构造函数
class Person{
    consructor(parent : Person){
        parent.children.add(this)
    }
}

//若没有声明任何构造函数,则会生成一个不带参数的主构造函数,默认为public。若主构造函数的所有参数都由默认值,也会生成一个默认的无参构造函数
class DontCreateMe private constructor(){}

//Kotlin中没有new关键字,创建类的实例。类似于调用方法
val invoice = Invoice()

继承与覆盖规则

Kotlin中所有类都继承于_Any_,类似于Java中的Object。若没有显式继承某个类,则默认继承自_Any_。语法如下:

//使用open 显式标记该类为用于继承的父类,Kotlin中所有类默认都为final 
open class Base(p:Int)

class Drived(p:Int) : Base(p)

/**如果该类有一个主构造函数,其基类型可以(并且必须) 用(基类型    的)主构造函数参数就地初始化。

如果类没有主构造函数,那么每个次构造函数必须使用 super 关键字初始化其基类型,或委托给另一个构造函数做到这一点。 注意,在这种情况下,不同的次构造函数可以调用基类型的不同的构造函数*/
class MyView : View {
    constructor(ctx: Context) : super(ctx)

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}

//成员若可以被覆盖,也需要标记为open,否则默认为final,重写方法必须显式使用override,若需要避免再次被覆盖,可以使用final
open class Base{
    open fun v() {}
    fun nv(){}
}
class Derived() : Base() {
    override fun v(){}
}

//属性同样可以被覆盖,但是规则如上。需要补充的是,var可以覆盖val,但反之则不行

//调用父类方法或构造,需要使用super关键字

//若需要在一个内部类访问外部类的父类,需要使用外部类名限定的super关键字来实现
class Bar : Foo(){
    override fun f() {}
    override val x : Int get() = 0
    inner class Baz{
        fun g(){
            super@Bar.f()
            println(super@Bar.x)
        }
    }
}
/**覆盖规则:
如果一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现(也许用继承来的其中之一)。 为了表示采用从哪个超类型继承的实现,我们使用由尖括号中超类型名限定的 super,如 super<Base>:*/
open class A{
    open fun f() { println("A")}
    fun a () { println("a") }
}
interface B{
    fun f() {println("B")}
    fun b() {println("b")}
}

class C():A(),B(){
    override fun f(){
        super<A>.f()
        super<B>.f()
    }
}

//Kotlin也有抽象类,但是抽象类不需要使用open来表示
open class Base{
    open fun f() {}
}
abstract class Derived : Base(){
    override abstract fun f()
}

//伴生对象,类似于Java的静态方法,调用方式一直,本质不同
class MyClass{
    companion object Factory{
        fun create() : Myclass = MyClass()
    }
}

val instance = MyClass.create()

属性

属性的声明,可用val和var

class Address{
    var name : String = ...
    var street : String = ...
    var city : String = ...
    var state : String? = ...
    var zip : String = ...
}

调用方式,Kotlin中没有new,类似于Java中public变量的访问方式

fun copyAddress(address : Address):Address{
    val result = Address()
    result.name = address.name
    ...
    return result
}

Getters与Setters语法

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

若属性类型可以从初始器推导出来,也可以省略

var allByDefault : Int? // 错误,这里需要显式初始化器
var initialized = 1 //默认推导为Int

自定义getter和settter

var stringRepersentation:String
    get() = this.toString()
    set(value){
        setDataFromString(value)
    }

每个属性的访问器都由一个幕后字段,使用field来表示

var counter = 0
    set (value){
        if(value >= 0){
            field = value
        }
    }

幕后属性

private var _table:Map<String , Int>? = null
public val table: Map<String , Int>
    get(){
        if(_table == null){
            _table = HashMap()
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

编译期常量,使用_const_修饰,类似于Java的static常量,但是Kotlin和Java的常量不能互相直接调用,若在Java中需要调用Kotlin的常量,需要加@JvmStatis的注解,例如:

const val SUBSYSTEM_DEPRECATED : String = "This subsystem is deprecated"
//可用于注解中
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo(){...}

延迟初始化属性

一般用于依赖注入这种情况,避免初始化前进行访问

public class MyTest{
    lateinit var subject : TestSubject
    
    @SetUp fun setup(){
        subject = TestSubject()
    }
    
    @Test fun test(){
        subject.method()
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值