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))
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号