IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android—Kotiln基础教程(六) -> 正文阅读

[移动开发]Android—Kotiln基础教程(六)

前言

在上一篇中,讲解了Kotlin关于对象的基础知识,在这一篇中,将会讲解Kotlin对应的对象,接口,抽象类相关的知识点。

1. 类的单例

1.1 示例一

object ApplicationConfig {

    init {
        println("loading config ...")
    }

    fun setSomeThing() {
        println("setSomething")
    }
}

fun main{
    ApplicationConfig.setSomeThing()
    println(ApplicationConfig) //
    println(ApplicationConfig)
    ApplicationConfig.setSomeThing()
}

我们这里看到,对象ApplicationConfig含有init初始化代码块,在main函数入口这,多次调用了ApplicationConfig对象。现在来看看运行效果:

loading config ...
setSomething
ApplicationConfig@63e31ee
ApplicationConfig@63e31ee
setSomething

从这个运行效果可知,当使用object修饰对象时,当前对象只能产生一个实例的类-单例!

既然如此,那如果说使用object修饰的对象继承了某个父类会怎样呢?

1.2 示例二

// 对象表达式
/*
* */
open class Player {
    open fun load() = "loading nothing"

    open fun add(one: Int, two: Int): Int {
        return one + two
    }
}

fun main{
    //对象表达式 ,类似于 设置按钮点击监听事件,用完就丢弃
    val p = object : Player() {
        override fun load() = "anonymous class load..."
        override fun add(one: Int, two: Int): Int {
            return one-two
        }
    }
    println(p.load())
    println(p.add(10, 20))
}

这里我们看到,定义了object对象继承了Player,并且重写了对应父类的方法,将原有逻辑改成了自己的。来看看运行效果:

anonymous class load...
-10

用这种方式,它的生命周期非常短,属于随用随丢的那种。

2. 类的嵌套

// 嵌套类
class Player2() {

    class Equipment(val name: String) {

        fun show() = println("equipment: $name")
    }

    fun battle() {
        Equipment("sharp knife").show()
    }
	//伴生对象,类似于java的static,里面闭包的方法可以直接通过类名.访问
    companion object {
        fun staticBattle() {
            Equipment("staticBattle knife").show()
        }
    }
}

fun main{
    //嵌套类
    Player2.Equipment("AK47").show()
    var p = Player2();
    p.battle();
    Player2.staticBattle()
}

这个使用了嵌套类,主要介绍的事,对象里面的方法有哪些方式能够访问。

普通方法battle,需要实例化Player2对象后才能访问;通过companion object闭包里的方法,可以直接通过类名.方法名的方式直接访问(类似java的static)

来看看运行效果:

equipment: AK47
equipment: sharp knife
equipment: staticBattle knife

这些都狠简单,直接过!

3. 数据类

数据类?那它有啥作用?

  • 数据类,是专门设计用来存储数据的类
  • 数据类提供了 toString的个性化实现
  • 符号默认情况下,比较对象就是比较他们的属性值,数据类提供了equals和hashCode的个性化实现
  • data 重写了 equals 和 hashCode 的实现

说了那么多!那它有啥使用条件?

  1. 数据类必须有至少带一个参数的主构造函数
  2. 数据类主构造函数的参数必须是val或var
  3. 数据类不能使用abstract、open、sealed和inner修饰符

概念说完了,实际体验一下。

3.1 示例一

data class Coordinate(var x: Int, var y: Int) {
    //坐标值是否正值
    val isInBounds = x >= 0 && y >= 0
}

fun main{
    println(Coordinate(1, 5))
    println(Coordinate(1, 5))
    println(Coordinate(1, 5) == Coordinate(1, 5)) //比较值
    println(Coordinate(1, 5) === Coordinate(1, 5)) //比较地址
}

这里看到使用也挺简单的,在main里面定义了两个值相同的Coordinate数据类,然后将它们的值和地址分别进行对等判断,来看看运行效果:

Coordinate(x=1, y=5)
Coordinate(x=1, y=5)
true
false

从这个运行效果可以看出,每次 创建的数据类,即使值相同,赋的初始值也相同,它们的地址都不相同。也就是说,每次创建数据类,它将开辟一个新的地址供自己使用。

3.2 示例二

data class Student(var name: String, var age: Int, val sex: Int) { //主构造函数
    var score = 10
    private val hobby = "music"
    var subject: String

    init {
        println("initializing student")
        subject = "math"
    }


    constructor(_name: String, _age: Int) : this(_name, _age, 1) { //第一个次构造
        score = 40
    }

    constructor(_name: String) : this(_name, 10, 2) { //第二个次构造
        score = 20
        subject = ""
    }

    override fun toString(): String {
        return "Student(name='$name', age=$age, sex=$sex, score=$score, hobby='$hobby', subject='$subject')"
    }
}

fun main{
    val s = Student("jack")
    println(s)
    var copy = s.copy("tom")
    println(copy)
    copy = s.copy("bob",30)
    println(copy)
}

这里使用了copy函数,将对象S的数据copy了一份。

注意看,代码里面除了主构造函数外,还额外定义了两个次构造函数。

先看运行效果:

initializing student
Student(name='jack', age=10, sex=2, score=20, hobby='music', subject='')
initializing student
Student(name='tom', age=10, sex=2, score=10, hobby='music', subject='math')
initializing student
Student(name='bob', age=30, sex=2, score=10, hobby='music', subject='math')

从这个运行效果可以看出:当使用copy复制对象时,将会copy里面的值将会带入主构造函数里,并非对应的次构造函数!

3.3 示例三

data class Coordinate2(var x: Int, var y: Int) {
    val isInBounds = x >= 0 && y >= 0

    operator fun plus(other: Coordinate2) = Coordinate2(x + other.x, y + other.y)

}
fun main{
    val c1 = Coordinate2(5, 6)
    val c2 = Coordinate2(10, 20)
    println(c1 + c2)
}

运行效果:

Coordinate2(x=15, y=26)

注意看,这里重载plus对应的操作符,于是乎Coordinate2具有加法运算。当使用数字符号+的时候就会调用对应plus方法。

4. 解构声明

在开始之前,要先明白何为解构?

还记得之前讲解过,可同时定义多个变量拆分集合/数组里面的每个元素么?

fun main
   val(a,b,c)= listOf("json", "jack", "jacky")
    println(a)
    println(b)
    println(c)
}

比如这样,定义a、b、c 分别拆分赋值集合里面的元素,这就是解构。当然这个是SDK帮我们封装好了。

那如果说,我们想要弄出这个格式该怎么办呢?

class PlayerScore(val experience: Int, val level: Int) {
    operator fun component1() = experience
    operator fun component2() = level
}

fun main{
    val (x,y)=PlayerScore(10,4)
    println(x)
    println(y)
}

这里我们看出:

  • 在Class对象里通过operator fun component1()指定了第一个变量的值和类型,
  • 通过operator fun component2()指定了第二个变量的值和类型
  • 同理operator fun component数字N() 指定了第N个变量的值和类型

注意:这里一定要按照顺序依次定义!

5. 枚举

5.1 示例一

//枚举类
enum class Direction {
    EAST,
    WEST,
    SOUTH,
    NORTH
}

fun main{
    println(Direction.EAST)
}

运行效果

EAST

这简单的不能再简单了,直接过!

5.2 示例二

data class Coordinate(var x: Int, var y: Int) {
  
}
enum class Direction2(private val coordinate: Coordinate) {

    EAST(Coordinate(5, -1)),
    WEST(Coordinate(1, 0)),
    SOUTH(Coordinate(0, 1)),
    NORTH(Coordinate(-1, 0));

    fun updateCoordinate(playerCoordinate: Coordinate): Coordinate {
    //使用 (Direction2.EAST对应的x,y与Coordinate对应的x,y进行对应的逻辑处理
        return Coordinate(playerCoordinate.x + coordinate.x, playerCoordinate.y + coordinate.y)
    }
}
fun main{
    println(Direction2.EAST.updateCoordinate(Coordinate(10,20)))
}

运行效果

Coordinate(x=15, y=19)

这也不怎么复杂,就是指定EAST枚举,将对应的x,y值与Coordinate里面的x,y值进行逻辑运算,最后再打印Coordinate对象。

5.3 示例三

enum class LicenseStatus {
    UNQUALIFIED,
    LEARNING,
    QUALIFIED;
}


class Driver(var status: LicenseStatus) {
    fun checkLicense(): String {
        return when (status) {
            LicenseStatus.LEARNING -> "在学习"
            LicenseStatus.QUALIFIED -> "有资格已毕业"
            LicenseStatus.UNQUALIFIED -> "没有资格"
        }
    }
}

fun main{
    var driver = Driver(LicenseStatus.QUALIFIED)
    println(driver.checkLicense())
}

运行效果

有资格已毕业

这个很简单,只要看了之前的语法,这应该能够一眼看出其意思!

但结合例子,思考一个场景:正常人在毕业后一般都会有个毕业编号啥的。但如果单靠枚举的话,只能确定这个人毕业了,并不能在确认的同时将毕业编号显示出来!但如果想要那种效果怎么办呢?

5.4 示例四(密封类)

sealed class LicenseStatus2 {
    object UnQualified : LicenseStatus2()
    object Learning : LicenseStatus2()
    class Qualified(val licenseId: String) : LicenseStatus2()
}

class Driver2(var status: LicenseStatus2) {
    fun checkLicense(): String {
        return when (status) {
            is LicenseStatus2.UnQualified -> "没有资格"
            is LicenseStatus2.Learning -> "在学习"
            is LicenseStatus2.Qualified -> "有资格,驾驶证编号:" +
                    "${(this.status as LicenseStatus2.Qualified).licenseId}"
        }
    }
}

fun main{
    var driver=Driver2(LicenseStatus2.Qualified("ds5464564"))
    println(driver.checkLicense())
}

注意这次并不是用的enum了,而是使用的sealed class,让它变成了密封类。当对应选项不需要参数时,可以使用object定义;当对应选项需要对应的属性值时,可以用class通过主构造函数将参数传入进去。

6. 接口

interface Moveable {
    val maxSpeed: Int
    var wheels: Int
    fun move(moveable: Moveable): String
}

class Car(_name: String, override var wheels: Int = 4) : Moveable {

    override val maxSpeed: Int
        get() = TODO("Not yet implemented")

    override fun move(moveable: Moveable): String {
        TODO("Not yet implemented")
    }


}

接口也挺简单的,和java几乎一致,就不过多演示了!

结束语

好了,本篇到这里就结束了!到现在为止,类的相关知识点已经讲解完毕!从下一篇开始将会讲解Kotlin对应的扩展以及函数式编程!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-14 21:50:06  更:2021-11-14 21:50:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:03:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码