kotlin类和对象

2019-05-30  本文已影响0人  覆水无言

一:类

kotlin使用class关键字来声明类

class Invoice{}
class Empty   //如果类没有实体可以省略{ }

二:构造函数

kotlin中一个类可以有一个主构造函数以及一个或多个次构造函数。

1.1:主构造函数

它跟在类名(与可选的类型参数)后,如果没有注解或可见性修饰符可以省略constructor关键字

class Person constructor(name: String) {}
class Person (name: String ){}     //这两个声明是一样的

主构造函数不能包含任何代码块, 初始化的代码可以放到以init关键字为前缀的代码块中。

class Person (val name: String) {
    val s  = "name $name".also(:: println)
    init {
        println("init name : $name")
    }
   val tian = "songtao $name".also(::println)
}

注意:主构造函数中的参数可以在初始化块中使用,也可以在类体内声明的属性初始化器中使用。
在类实例化期间,初始化块和属性初始化器按住在类中编码的顺序执行。

1.2:次构造函数

类也可以声明前缀有constructor的次构造函数,如果一个类中有主构造函数那么每一个次构造函数都需要
委托给主构造函数,可以直接委托也可以通过别的次构造函数委托,委托同类构造函数使用this关键字

class Person (val name: String) {
    val s  = "name $name".also(:: println)
    init {
        println("init name : $name")
    }
    val tian = "tian name: $name".also(:: println)

    constructor(name: String, age: Int): this(name) {

    }
}

注意:初始化块中的代码实际会作为主构造函数的一部分,委托给主构造函数实际上会作为次构造函数的第一条代码执行。因此初始化块都是执行在次构造函数之前,即使没有主构造函数这种委托也会隐式存在。
如果一个类没有任何主次构造函数,它会生成一个不带参数的主构造函数,如果你想你的类没有一个公共的主构造函数,可以用限制符声明它的非公共主构造函数

class Tian private constructor(){}

三:创建类的实例

kotlin中没有Java的new关键字,实例化类像普通函数一样调用构造函数

val person = Person("tian")

四:类成员

类的成员包括

五:继承

kotlin中所有的类都有一个共同的超类Any, 和Java中的object一致,没有超类声明的类Any就是它的默认超类,要声明一个超类,我们把类型放到类头的冒号后. kotlin力求显示清晰,与Java不同,kotlin对于公开的超类和可重写的函数都需要用时open关键字来显示指定公开,类似java中的public。

open class Person
class Man : Person
open class Woman(name:String): Person()
class Student(name:String): Woman(name)  
class MyView: View{
    constructor(context: Context): super(context)
    constructor(context: Context, attrs: AttributeSet): super(context, attrs)
}

注意:如上,如果子类有主构造函数,那么超类就可以直接用子类主构造函数中的参数直接初始化。如果类没有主构造函数,那么每个次构造函数都需要使用super关键字来初始化超类,也可以委托给其他次构造函数,不同次构造函数也可以调用不同的超类次构造函数。

六:覆盖方法

可以被子类覆盖的方法为公开方法,也需要使用open显示指定

open class Person{
    open fun open(){
        println("open")
    }

    fun unOpen(){  //没有open显示指定,这个函数不能被重写覆盖,
        println("unOpen")
    }
}

class Man : Person(){
    override fun open() {    //这里必须使用override关键字来修饰,
        super.open()
    }
    final override fun open(){  //子类不可在覆盖
      super.open()
    }
}

注意:不可覆盖的方法在子类和超类中不可有相同函数名的函数,也就是Man类中不可定义超类的unOpen函数。override本身就是open的,Man的子类也可覆盖open函数,如果不想覆盖就使用final关键字修饰。

七:覆盖属性

覆盖属性和覆盖方法类似。

八:调用超类的实现

1.1:子类调用超类函数使用super关键字,

class Man : Person(){
    override fun open() {    //这里必须使用override关键字来修饰,
        super.open()
    }
}

1.2:子类内部类调用子类超类。

内部类调用外部类的超类可以使用super关键字的限定名来实现,super@outer

class Man: Person(){
      override fun open(){
          super.open()
      }
      inner class student{
          fun g(){
              super@Man.open()  //这里使用@标记super为谁的super,这里这个关键字super是Man的super,
                    //所以这个super@Man.open()调用的是Man的超类Person的open函数。  
          }
      }
}

1.3:多超类情况

如果一个类从它的直接超类继承相同成员的多个实现,它必须覆盖(重写)这个成员并自己实现,为了表明
采用的的那个超类继承的实现,可以使用super<超类名>来限定是那个超类。

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

interface B {
    fun f(){}
}

class C: A(), B {
    override fun f() {
        super<A>.f()  //super后跟<超类名>来标记调用的是那个超类的函数
        super<B>.f()
    }
}

九:抽象类

kotlin中抽象类和Java中的类似,抽象类中的抽象函数可以没有函数体。抽象函数自带open不用显示声明

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

abstract class B: A() {
    override abstract fun f()
}
上一篇 下一篇

猜你喜欢

热点阅读