Kotlin入坑(四)类和继承一

来源:互联网 发布:linux中export命令 编辑:程序博客网 时间:2024/06/03 15:16

kotlin中的类跟java一样使用class声明

class Person {}

但是构造函数跟Java不同 使用constructor关键字 constructor前面可以添加类的控制域,比如private,public 如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

class Person constructor(name: String) {}class Person private constructor(name: String) {//添加可见性修饰符}class Person(name: String) {//省略constructor}

我们一般会在构造函数中初始换一些东西,但是主构造函数中不能包含代码,所以初始化的工作放到 init 关键字里面

class Person(name: String) {    init {          //初始化的工作       }}

主构造函数中的参数可以在类中直接使用

class Person(name: String) {    val customerKey = name.toUpperCase()}

多构造

//没有主构造函数

class Person{//多构造    constructor(name:String)    constructor(name: String,email: String)    constructor(name: String,email: String,address:String)}

如果类有一个主构造函数,那么每个次构造函数需要委托给主构造函数 使用 this 关键字

class Person(name:String){    constructor(name: String,email: String):this(name)    constructor(name: String,email: String,address:String):this(name)}

注意:在 JVM 上,如果主构造函数的所有的参数都有默认值,编译器会生成 一个额外的无参构造函数,它将使用默认值。 比如:

class Person(val name: String = "")

上面的类在创建的时候就可以如下两种 kotlin创建实体类不需要new关键字

 var person = Person() var person1 = Person("张三")

继承

kotlin中没有java中的extends和implements关键字,继承和实现接口使用关键字 一个冒号解决

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

open class Person(name:String)class Student(name:String) : Person(name)

类上的 open 标注与 Java 中 final 相反,它允许其他类从这个类继承。默认情况下,在 Kotlin 中所有的类都是 final

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

open class Person{    constructor(name:String)    constructor(name: String,age:Int)}class Student : Person{    constructor(name:String) : super(name)    constructor(name:String,age:Int):super(name,age)}

覆盖方法

如果父类的方法可以让子类覆盖 必须使用 open 关键字声明

open class Person{    constructor(name:String)    constructor(name: String,age:Int)    open fun eat(){    }}

而子类如果要覆盖父类的方法 需要用 override关键字声明

class Student : Person{    constructor(name:String) : super(name)    constructor(name:String,age:Int):super(name,age)    override fun eat() {        super.eat()    }}

标记为 override 的成员本身是开放的,也就是说,它可以在子类中覆盖。如果你想禁止再次覆盖,使用 final 关键字

在内部类中方为外部类的父类可以通过由外部类名限定的 super 关键字来实现:super@Outer:Outer代表外部类

class Student : Person{    constructor(name:String) : super(name)    constructor(name:String,age:Int):super(name,age)    override fun eat() {        super.eat()    }    inner class mouth{        fun go(){            super@Student.eat()        }    }}

如果子类继承了两个父类,两个父类中有一个方法的名字相同,那么子类实现该方法的时候,需要注明super<Base>是哪个父类的方法。 base代表父类

抽象类

跟java一样使用abstract关键字修饰

abstract class Person{    abstract fun eat()}

静态方法

kotlin中没有static关键字。我们平时开发中经常使用到一些工具类,使用类名直接调用类中的方法。在kotlin中
companion object来包裹方法即可 比如:

class ImageLoader{    companion object{        //默认加载        fun loadImageView(mContext: Context, path: String, mImageView: ImageView) {            Glide.with(mContext).load(path).into(mImageView)        }    }}

也可以直接使用 object 关键字声明

object ScreenUtil{    fun dip2px(context: Context, dpValue: Float): Int {        val scale = context.resources.displayMetrics.density        return (dpValue * scale + 0.5f).toInt()    }}

调用的时候就可以

ImageLoader.loadImageView(context, url,imageview)ScreenUtil.dip2px(this,12f)

属性和字段

Kotlin的类可以有属性(成员变量常量)。 属性可以用关键字var 声明为可变的,用键字val声明常量。

class Man{    val type= "man"    var name:String = ""    var age: Int = 30}

使用也很方便

val man = Man()var name = man.namevar age = man.age

const可以用来定义编译时常量,但是const只能用在顶级属性,以及object对象的属性中

package com.chs.kotlintextconst val TEG = "man"class Man{    object SmallMan{        const val TEG = "small_man"    }    val type = "man"    var name:String = ""    var age: Int = 30}

延迟初始化属性与变量 使用 lateinit 关键字

class Man{    lateinit var girl : Girl}

该修饰符只能用于在类体中的属性(不是在主构造函数中声明的 var 属性,并且仅当该属性没有自定义 getter 或 setter 时),而自 Kotlin 1.2 起,也用于顶层属性与局部变量。该属性或变量必须为非空类型,并且不能是原生类型。
在初始化前访问一个 lateinit 属性会抛出一个特定异常,该异常明确标识该属性被访问及它没有初始化的事实
自 1.2 起可以检测一个 lateinit var 是否已初始化 使用 .isInitialized

原创粉丝点击