Android Kotlin入门-类和继承

正文:

Classes

在KotLin里定义类的形式如下:

class Invoice {
}
类的声明包括类的名称、类的标题(类的参数、主构造参数)和类主体、所包含的花括号,类的标题和类主体是可选择的,如果类的主体不存在则花括号可以省略形如:

class Empty

Constructors

一个类在KotLin里面有一个主构造函数和好多的辅助构造函数,这个主构造函数是上面类声明类标题的一部分,放在类名称的后面

class Person constructor(firstName: String) {
}
如果类没有注释和是否可见修饰(public private)
class Person(firstName: String) {
}
主构造函数不包括任何的代码,如果想做初始化操作可以在init代码块中进行初始化

class Customer(name: String) {
    init {
        logger.info("Customer initialized with value ${name}")
    }
}

在init初始化代码块中可以访问主构造函数的参数,在类主体也可以访问在初始化代码块操作之后的值,形如:

class Customer(name: String) {
        val customerKey = name.toUpperCase()
        init{
            System.out.println("执行了初始化代码块")
            var ini : Int = 10
            var str : String = "Andly"
        }

        constructor(n : Int) : this(""){
            //这里不能访问name
            System.out.println("执行了辅助代码")
        }

    }
事实上声明参数和初始化他们可以在主构造函数,在KotLin有这个用法。形如:(var是可变的,val是只读)

class Person(val firstName: String = "a", val lastName: String = "b", var age: Int) {
        
    }

Secondary Constructors

给一个类声明辅助构造函数,前缀要加 constructor。形如:

class Person {
    constructor(parent: Person) {
        parent.children.add(this)
    }
}
如果一个类中有了主构造函数,那么在定义辅助构造函数的时候也需要对主构造函数进行初始化(直接或间接).形如:

  class Person(val name: String) {
        //直接初始化主构造函数
        constructor(name: String, parent: Person) : this(name) {
            
        }
        
        //间接初始主构造函数
        constructor(a : Int) : this("",Person("")){
            
        }
    }
如果你定义类不是一个抽象类并且没有声明构造函数(主构造和辅助构造函数)那么你的主构造函数是public的,如果你不想让你的主构造函数是public的话,你只需要在 constructor前面加上你的修饰符。形如:

class DontCreateMe private constructor () {
}
tip:如果在构造函数声明了参数,那么那参数会根据类型分配默认值

Creating instances of classes

形如:

val invoice = Invoice()

val customer = Customer("Joe Smith")
在KotLin没有new关键字

Inheritance

对于没有声明父类的类默认父类为Any(不是java.lang.Object没有equal等方法)

显示声明父类,形如:

open class Base(p: Int)

class Derived(p: Int) : Base(p)
如果这个类没有主构造函数,那样每个辅助构造函数必须要初始化基类的构造,使用super关键字,不同的辅助构造函数可以初始化基类不同的构造方法。形如:

class MyView : View {
    constructor(ctx: Context) : super(ctx) {
    }

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
    }
}
这个open注解和final相反,它允许被继承。默认是final类型

Overriding Members

不像java,在KotLin要求在重写的方法前面写override.形如:

open class Base {
  open fun v() {}
  fun nv() {}
}
class Derived() : Base() {
  override fun v() {}
}
一个类的方法用了override,说明它自己是open,这个类的子类还可以覆盖这个方法。如果不想让它覆盖则在前面声明final类型。形如:

open class AnotherDerived() : Base() {
  final override fun v() {}
}

Overriding Rules

如果你的类继承了父类,并且想要在你的类中去访问父类的方法,只需要使用super.形如:

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.f() // call to A.f()
    super.f() // call to B.f()
  }
}

Abstract Classes

一类及其成员可以声明为抽象。抽象成员在类中没有实现。请注意,我们不需要对一个抽象类或函数进行注释,它不用说。形如:

open class Base {
  open fun f() {}
}

abstract class Derived : Base() {
  override abstract fun f()
}

Sealed Classes

密封类用于表示受限的类层次结构,当一个值可以从一个有限集合的类型中具有一个类型,但不能有任何其他类型的类型。他们,在某种意义上,枚举类的扩展:一个枚举类型的值的集合也受到了一定的限制,但每个枚举常量的存在不仅是一个实例,而一个密封类可以有多个实例可以包含状态。形如:

sealed class Expr {
    class Const(val number: Double) : Expr()
    class Sum(val e1: Expr, val e2: Expr) : Expr()
    object NotANumber : Expr()
}
fun eval(expr: Expr): Double = when(expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
    // the `else` clause is not required because we've covered all the cases
}


你可能感兴趣的:(Android开发)