从零开始的Kotlin之类和对象(一)

423 查看

从零开始系列:

构造器

主构造器

Koltin 中的类可以有一个 主构造器,以及一个或多个 次构造器,主构造器是类头部的一部分,位于类名称之后

class Person constructor(firstName: String) {}

如果主构造器没有任何注解,也没有任何可见度修饰符,那么constructor关键字可以省略。
主构造器中不能包含任何代码,初始化代码可以放在 初始化代码段中,初始化代码段使用 init关键字作为前缀。

class Person constructor(firstName: String) {
    init {
        System.out.print("FirstName is $firstName")
    }
}

注意:主构造器的参数可以在初始化代码段中使用,也可以在类主体n定义的属性初始化代码中使用。
一种简洁语法,可以通过主构造器来定义属性并初始化属性值(可以是var或val):

class People(val firstName: String, val lastName: String) {
    //...
}

如果构造器有注解,或者有可见度修饰符,这时constructor关键字是必须的,注解和修饰符要放在它之前。

次构造器

使用constructor关键字作为前缀:

class Person {
    constructor(parent: Person) {
        parent.children.add(this )
    }
}

如果类有主构造器,那么每个次级构造器都必须委托给主构造器,要么直接委托,要么通过其他次级构造器间接委托。委托到同一个类的另一个构造器时,使用this关键字实现。

class Person constructor(firstName: String) {
    constructor() : this("Hello") {
    }
}

如果一个非抽象类没有声明任何主构造器和次构造器,那么它将带有一个自动生成的,无参数的主构造器,可见度为 public。

对象

创建对象

调用类的构造器,调用方式和使用普通函数一样:

val person = Person("Juhezi")

注意:Kotlin 没有 new 关键字。

继承

Kotlin 中所有类都有一个共同的超类Any,如果类声明时没有g指定超类,则默认为Any

注意Any不是java.lang.Object,只有equals()hashCode()toString()三个方法。

Kotlin中使用:来实现继承,而不是extends

open class Base(p: Int)
class Derived(p: Int): Base(p)

如果类有主构造器,那么必须在主构造器中使用主构造器的参数来初始化父类。如果类没有主构造器,那么所有的次级构造器都必须使用superi关键字来初始化父类,或者委托到另一个构造器,由被委托的构造器来初始化父类。

open关键字表示允许从这个类继承出其他子类,作用和final关键字作用相反。默认情况下,Kotlin中所有的类都是 final 的。

抽象类

类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。

注意:无需对抽象类或抽象成员标注open注解。

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

同伴对象(Companion Object)

Koltin没有静态方法(static method),可以使用同伴对象代替。
如果在类中声明一个同伴对象,那么只需要使用类名就可以调用调用同伴对象的成员了。

class Util {
    companion object {
        val element: String = "HelloWorld"
        fun sayHello() {
            System.out.println(element)
        }
    }
}

class Main {
    init {
        System.out.println(Util.element)
        Util.sayHello()
    }
}

封闭类

封闭类用来表示对类阶层的限制,可以限定一个值只允许是某些指定的类型之一,而不允许是其他类型。

要声明一个封闭类,需要将sealed修饰符放在类名之前,封闭类可以有子类,但所有的子类声明明都必须嵌套在封闭类的声明部分之内。

sealed class Expr {
    class Const(val number: Double) : Expr()
    class Sum(val e1: Expr, val e2: Expr) : Expr()
    object NotANumber : Expr()
}

注意:从封闭类的子类再继承的子类(间接继承者)可以放在任何地方,不必在封闭类的声明部分之内。