Kotlin入门第五节

继承与重写

  • kotlin所有的类默认都是被final修饰的,不能被集成想要被集成需要用到open关键字
  • kotlin默认所有的方法也是final修饰的,想要被重写可以使用open修饰
open class Father(var name: String) {
    private fun showName() {
        println("父方法" + this.name)
    }

    open fun myname() {
        println(this.name)
    }
}

class Son(var names: String) : Father(names) {
    override fun myname() {
        println("子方法" + this.names)
    }
}

fun main() {
    var person: Father = Son("老黑")
    println(person.myname())
}

类型判断和类型转换

  • 类型判断
 var person: Father = Son("老黑")
    println(person is Father)
    println(person is Son)
    println(person is File)
  • 类型转换
var person: Father = Son("老黑")
    println(person is Father)
    println(person is Son)
    println(person is File)

    if(person is Father){
        (person as Father).showName()
    }
    if(person is Son){
        (person as Son).showName()
    }

Any

  • Any类似Java中的Object,只提供标,看不到实现,实现在各个平台处理好了,Kt中的任何类都继承了Any

object关键字

  • object修饰的类,只会有一个示例,类似单例
package com.fyx.s1

import sun.plugin.dom.core.Text


//构造器执行顺序,init相当于java的构造器{}
object KtBase2{

    init {
        println("构造执行了")
    }

     fun show(){
        println("修饰单例模式")
    }
}

fun main() {
    println(KtBase2)
    println(KtBase2)
    println(KtBase2)
    println(KtBase2)
    println(KtBase2.show())
}

对象匿名

  • 使用object写法
open class Person {
    open fun showmyTest(name: String) {
        println("原始函数")
    }
}

fun main() {
    var name: Person = object : Person() {
        override fun showmyTest(name: String) {
            println("匿名构造")
        }
    }
    name.showmyTest("老黑")
}

伴生对象

  • 因为kotlin没有static静态关键字,所以使用 companion object 来表示
  • 无论对象构建多少次,伴生对象只存在一次
  • 伴生对象只会初始化一次
class Person {
    companion object {
        var configUrl = "http://baidu.com"
    }
}

fun main() {
    println(Person.configUrl)
}

内部类和嵌套类

  • 使用inner修饰内部类可以实现内部类访问外部类,且外部类也可以访问内部类
class Body {
    var name = "身体"
    //外访问内
    var heartname = Heart().heartsname

    inner class Heart() {
        var heartsname = "心脏"

        //内访问外
        fun showName() {
            println("我的信息是$name")
        }
    }

}
  • 默认不使用inner就是嵌套类,只能外部类访问内部类,不可内部类访问外部类
class Body {
    var name = "身体"
    //外访问内
    var heartname = Heart().heartsname

     class Heart() {
        var heartsname = "心脏"

        //内访问外
        fun showName() {
            //报错
            println("我的信息是$name")
        }
    }

}

普通类和数据类

  • 普通类就是使用class修饰的类(会根据构造生成默认的字段和get,set 方法)
  • 数据类是使用data class 修饰的类(会根据构造生成默认的字段和get,set 方法,结构操作和重写 copy,tostring,hashcode,equals函数)

区别就在于数据类比普通类所提供的方法多

class ResultData1(var code: Int, var mes: String, var data: String) {

}

data class ResultData2(var code: Int, var mes: String, var data: String) {

}

fun main() {
    //普通类
    println(ResultData1(200,"成功","一条数据"))
    //ResultData1@266474c2

    //数据类
    println(ResultData2(200,"成功","一条数据"))
    //ResultData2(code=200, mes=成功, data=一条数据)


    //比较 因为没有重写equals 所以默认比较的是地址值,所以是false
    println(ResultData1(200,"成功","一条数据")==ResultData1(200,"成功","一条数据"))
    //false

    //比较 因为没有重写equals 所以默认比较的是地址值,所以是false
    println(ResultData2(200,"成功","一条数据")==ResultData2(200,"成功","一条数据"))
    //true
}

结构化声明

  • 结构化声明是一种简单快捷的数据取值,数据类默认是生成了结构化函数

注意:结构化函数必须命名成component1 以此类推

class ResultData1(var code: Int, var mes: String, var data: String) {

    operator fun component1() = code
    operator fun component2() = data
    operator fun component3() = mes
}

data class ResultData2(var code: Int, var mes: String, var data: String) {

}

fun main() {
    var (name, data, sex) = ResultData1(12, "描述", "数据")
    println("$name$data $sex")

    var (names, datas, sexs) = ResultData2(12, "描述", "数据")
    println("$names$datas $sexs")
}

运算符重载

  • 运算符重载plus做运算
class Math(var num1: Int, var num2: Int) {
    operator fun plus(data1: Math): Int {
        return (this.num1 + data1.num1) * (this.num2 + data1.num2)
    }
}

fun main() {
    println(Math(1,2) + Math(1,2))
}

枚举类型

enum class Week {
    星期一,
    星期二,
    星期三
}

data class Info(var name: String, var size: String) {
    fun show() {
        println("${this.name}长度是$size")
    }
}

enum class BodyInfo(private var info: Info) {
    Head(Info("头", "20")),
    Hand(Info("手", "30")),
    Body(Info("身体", "20"));

    fun show() {
        println("${this.info.name} ${this.info.size}")
    }

    fun updateData(info: Info) {
        this.info.size = info.size
        this.info.name = info.name
        println("${this.info.name} ${this.info.size}")
    }
}

fun main() {
    println(Week.星期一)
    println(Week.星期三 is Week)

    //常用枚举
    BodyInfo.Body.show()
    BodyInfo.Hand.updateData(Info("我不是手,我是胳膊","长度20公分"))
}

密封类

根据下面的代码,我们想要打印出成绩优秀的学生名字,那么使用传统的枚举是实现不了的,我们可以使用密封类(sealed)来实现

enum class Week {
    S1,
    S2,
    S3,
    S4
}

class Teacher(private var data: Week) {
    fun show() =
        when (this.data) {
            Week.S1 -> "很差"
            Week.S2 -> "及格"
            Week.S3 -> "良好"
            Week.S4 -> "优秀"
        }
}
fun main() {
    println(Teacher(Week.S1).show())
}
  • 密封类的特点,所有的类都需要集成原密封类
sealed class Week {
    object S1 : Week()
    object S2 : Week()
    object S3 : Week()
    class S4(var stuName: String) : Week()
}

class Teacher(private var data: Week) {
    fun show() =
        when (this.data) {
            is Week.S1 -> "很差"
            is Week.S2 -> "及格"
            is Week.S3 -> "良好"
            is Week.S4 -> "优秀该学生的名字是${(this.data as Week.S4).stuName}"
        }
}

fun main() {
    println(Teacher(Week.S1).show())
    println(Teacher(Week.S4("李雷")).show())
}

这里可能会存在疑问,为什么又成员变量的类需要使用class而不是object,因为其他类都是单例,使用object 来创建的枚举至始至终都是一个对象,而class对象的类可以是多个

接口

interface USB {
    var name: String
    var info: String
    fun show(): String

}

class Mouse(override var name: String = "鼠标", override var info: String = "雷蛇鼠标") : USB {
    override fun show(): String {
        return "${this.name}${this.info}"
    }
}

class KeyWorld(override var name: String = "键盘", override var info: String = "雷蛇键盘") : USB {
    override fun show(): String {
        return "${this.name}${this.info}"
    }
}

fun main() {
    println(Mouse().show())
    println(KeyWorld().show())
}

抽象类

  • 一些流程相似,但是内部具体实现不同的可以使用抽象类
abstract class Layout {
    fun load() {
        setContentView(getWeight())
        this.initView()
        this.initData()
        this.initXXX()
    }

    private fun setContentView(weight: Int) {
        println("我的宽度是${weight}")
    }

    abstract fun getWeight(): Int

    abstract fun initView()

    abstract fun initData()

    abstract fun initXXX()
}

class AppLayOut : Layout() {
    override fun getWeight(): Int {
        return 100
    }

    override fun initView() {
        println("初始话视图")
    }

    override fun initData() {
        println("初始化数据")
    }

    override fun initXXX() {
        println("初始化XXX")
    }

    fun show() {
        super.load()
    }
}

fun main() {
    AppLayOut().show()
}

泛型

泛型就是将类型以参数的方式进行传递,从而提高代码的扩展性

//万能输出器
class DataOutm<T>(var data: T) {
    fun show() {
        println("万能输出${data.toString()}")
    }
}

data class Person(var name: String, var age: Int) {

}
data class Foot(var name: String, var price: Double) {

}

fun main() {
    var Jack=Person("老王",18)
    var Apple=Foot("苹果",18.0)
    DataOutm<Person>(Jack).show()
    DataOutm<Foot>(Apple).show()
}

vararg 可变参数

类似与Java中的参数…

//vararg 表示可以传入任意类型的参数
class DataOutm<T>(vararg data: T, var flag: Boolean) {

    //out 我们的T只能被读取,不能被修改 T只能读取
    private val objdata: Array<out T> = data

    //返回数据的值
    public fun showData(index: Int): T? {
        return objdata[index]
    }
}

fun main() {
    //默认的泛型是<Any>
    var data=DataOutm("我是字符串",12,"I",12.01f,54.21,null ,flag = false)
    println(data.showData(0))
    println(data.showData(1))
    println(data.showData(2))
    println(data.showData(3))
    println(data.showData(4))
    println(data.showData(5))
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值