Android Kotlin 类和接口(二)

首先申明下,本文为笔者学习《Kotlin 程序开发入门精要》的笔记,并加入笔者自己的理解和归纳总结。

1. 类

在kotlin中,类的声明使用class关键字。

class Shape {
}

1.1 构造器

类允许定义一个主构造器和若干个第二构造器。
主构造器是类头的一部分,紧跟在类名的后面,构造器参数是可选的。在init块中进行初始化,init块可直接使用主构造器的参数。

class Shape constructor(w: Int, h: Int) {
    var width: Int = w
    var height = h

    init {
        println("Shape init width = $width, height = $height")
    }

}

如果主构造器没有任何的注释(annotation)或修饰符(modifier)constructor关键字可以省略。

class Shape(w: Int, h: Int) {
    ... ...
}

第二构造器需要在类中声明,前面必须加constructor关键字,并且都需要在声明后面调用主构造器或通过另一个第二构造器间接地调用主构造器。

class Shape(w: Int, h: Int) {
    var width: Int = w
    var height = h

    init {
        println("Shape init width = $width, height = $height")
    }

    constructor(w: Int): this(w, 10) {
        println("Shape constructor(w)")
    }

    constructor(): this(20) {
        println("Shape constructor()")
    }

}

1.2 类属性

属性语法,只有var/valpropertyName是必须的,其他都是可选的。

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

属性的gettersetter形式 ,可以拦截属性读写。如果属性是只读的,需要将属性声明为val,并只添加一个getter形式。如果属性是读写的,需要使用var声明,并添加gettersetter形式。如果getter只有一行实现代码,直接用等号(=)分割。

class Property {
    private var value = 4
    var prop: Int
        get() {
            println("get prop")
            return value
        }
        set(v) {
            println("set prop")
            value = v
        }

    var prop2: Int = 20
        get() = field
        set(v) {
            field = v
        }
}

上面的例子里prop属性用value来保存属性的值,kotlin为我们提供了更好的解决方式,filed属性。不能对直接对prop进行赋值,否则会报"Initializer is not allowed here because this property has no backing field",详见Kotlin 的 Backing Fields 和 Backing Properties

1.3 类函数

kotlin函数支持默认参数,但带默认参数的必须是最后几个参数。调用时,可以按顺序传入参数值,也可以通过指定函数的形参名传值。

class Function {

    fun show(i: Int = 5, d: Double = 10.0, flag: Boolean = false) {
        println("i = $i, d = $d, flag = $flag")
    }

}

fun main(args: Array<String>) {
    var f = Function()
    f.show(1, 2.0, true)  // i = 1, d = 2.0, flag = true
    f.show(15, 25.0)  // i = 15, d = 25.0, flag = false
    f.show(6, flag = true)  // i = 6, d = 10.0, flag = true
}

可变参数使用vararg声明

fun addFunction(vararg functions: Function): List<Function> {
    var list = ArrayList<Function>()
    for (f in functions) {
        list.add(f)
    }
    return list
}

1.4 嵌套类

所谓嵌套类,就是在类中定义的类。如果用inner关键字声明,需要通过外部类的实例引用嵌套类。

class Outer {

    class Nested {
        fun show() {
            println("Outer.Nested")
        }
    }

    inner class Inner {
        fun show() {
            println("Outer.Inner")
        }		
    }

}

fun main(args: Array<String>) {
    Outer.Nested().show()  // Outer.Nested
    Outer().Inner().show()  // Outer.Inner
}

2. 修饰符

在Kotlin中,修饰符有4个,privateprotectedinternalpublic。如果不指定,默认是public

  • private,仅仅在类的内部可以访问。
  • protected,除了类内部,子类中也可以访问
  • internal,在模块内部类都可以访问
  • public,任何类都可以访问

3. 类的继承

Kotlin使用冒号(:)实现继承,冒号后面需要调用父类的构造器。Kotlin是单继承,默认是final,需要显式使用open关键字来继承类。

open class Shape(w: Int, h: Int) {
    var width: Int = w
    var height = h

    ... ...
}

class Rectangle(w: Int, h: Int): Shape(w, h) {        

}

类方法默认是不可重写的,如果需要重写方法,先需要在父类的方法前加上open关键字,同时在子类的方法前加上override关键字。

open class Rectangle(w: Int, h: Int): Shape(w, h) {        

    override fun toString(): String {
        return "rectangle width = $width, height = $height"
    }

}

重写方法可以被再次重写,如要阻止可添加final关键字。

class Square(l: Int): Rectangle(l, l) {

    final override fun toString(): String {
        return "Square width = $width, height = $height"
    }

}

重写属性必须使用open声明,子类中重写的属性必须用override声明。val属性可以被重写为var属性,反之不可以。

open class Shape(w: Int, h: Int) {
    var width: Int = w
    open val height: Int = h
        get() {
            println("Shape getHeight")
            return field	
        }

    ...  ...
}

open class Rectangle(w: Int, h: Int) : Shape(w, h) {
    override var height: Int = h
        get() {
            println("Rectangle getHeight")
            return field	
        }
        set(height) {
            println("Rectangle setHeight")
            field = height
        }

    ...  ...
}

fun main(args: Array<String>) {
    var r = Rectangle(10, 15)
    println(r.height)
    r.height = 20
    println(r.height)
    println(r)
}

输出

Rectangle getHeight
Shape init width = 10, height = 0
Rectangle getHeight
15
Rectangle setHeight
Rectangle getHeight
20

4. 接口

接口使用interface声明,接口中的属性和方法都是open的。kotlin允许在接口方法中包含默认的方法体。

interface IShape {
    fun getArea(): Int
    fun getName() = ""
}

open class Shape(w: Int, h: Int): IShape {
    var width: Int = w	    
    val height = h

    override fun getArea(): Int {
        return width * height
    }

}

5. 抽象类

抽象类与接口类似,需要abstract关键字声明。

abstract class Base {
    abstract fun f()
}

class Super : Base() {
    override fun f() {}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值