【Kotlin 初学者】枚举类-密封类-数据类-继承(上)

简介: 目录一、枚举类1.1 创建枚举类1.2 获取枚举相关信息1.3 枚举类添加属性1.4 定义函数1.5 以泛型的方式访问枚举类中的常量1.6 代数数据类型(ADT)二、密封类(sealed class)2.1 创建密封类2.2 使用


一、枚举类


       枚举类,用来定义常量集合的一种特殊类。使用 enum class 可以声明一个枚举类


1.1 创建枚举类


       枚举常量用逗号分隔,每个枚举常量都是一个对象


enum class Color{
    RED,
    BULE,
    YELLOW
}
fun main() {
    //使用
    println(Color.RED)
}


微信图片_20220524203005.png


1.2 获取枚举相关信息


val name: String //获取枚举名称,,默认名称为枚举字符名
val ordinal: Int //获取枚举值在所有枚举数组中定义的顺序,值从 0 开始


fun main() {
    //使用
    val blue = Color.BULE
    println(blue.name)
    println(blue.ordinal)
}


微信图片_20220524203046.png


1.3 枚举类添加属性


       每一个枚举都是枚举类的实例,它们可以被初始化。

       若需要指定值,则可以使用其构造函数。


//2.0版本
enum class Color2(val user: UserColor) {
    RED(UserColor("小红", 15)),
    BULE(UserColor("小蓝", 20)),
    YELLOW(UserColor("小黄", 30));
}
data class UserColor(val name: String, val age: Int)
fun main() {
    //2.0版本
    println(Color2.BULE.user)
}


微信图片_20220524203204.png


1.4 定义函数


enum class Color2(val user: UserColor) {
    ...
    RED(UserColor("小红", 15));
    fun addUser(adduser:UserColor)=
        UserColor("${adduser.name}-${user.name}"
            ,adduser.age+user.age)
}
fun main() {
    //枚举定义函数
    println(Color2.RED.addUser(UserColor("新", 40)))
}


微信图片_20220524203235.png


1.5 以泛型的方式访问枚举类中的常量


       Kotlin 1.1 起,可以使用 enumValues()enumValueOf()函数以泛型的方式访问枚举类中的常量


@SinceKotlin("1.1")
public inline fun <reified T : Enum<T>> enumValues(): Array<T>
/**
 * Returns an enum entry with specified name.
 */
@SinceKotlin("1.1")
public inline fun <reified T : Enum<T>> enumValueOf(name: String): T
//使用
fun main() {
    println(enumValueOf<Color>("RED"))
    println(enumValues<Color2>().joinToString { it.user.toString() })
}

微信图片_20220524203405.png


1.6 代数数据类型(ADT)


       可以用来表示一组子类型的闭集,枚举类就是一种简单的ADT。

       使用枚举的关键好处在于使用 when 表达式的时候,如果能够 验证语句覆盖了所有情况,就不需要为该语句再添加一个 else 子句了。


enum class ColorADT {
    RED,
    BULE,
    YELLOW
}
class TakeColor(var colorADT: ColorADT) {
    fun selectColor(): String {
        return when (colorADT) {
            ColorADT.RED -> "红色"
            ColorADT.BULE -> "蓝色"
            ColorADT.YELLOW -> "黄色"
             // 不再需要 `else` 子句,因为我们已经覆盖了所有的情况
        }
    }
}
fun main() {
    println(TakeColor(ColorADT.BULE).selectColor())
}


微信图片_20220524203437.png


 但是如果我们想在返回是红色的时候给一个提示。如果使用枚举类,那么还需要判断就有一些复杂了。对于更复杂的ADT,你可以使用Kotlin的密封类(sealed class)来实现更复杂的定义。


二、密封类(sealed class)


  • 对于更复杂的ADT,你可以使用Kotlin的密封类(sealed class)来实现更复杂的定义,密封类可以用来定义一个类似于枚举类的ADT,但你可以更灵活地控制某个子类型。


  • 密封类可以有若干个子类,要继承密封类,这些子类必须和它定义在同一个文件里。


  • sealed 关键字不能修饰 interface ,abstract class(会报 warning,但是不会出现编译错误)


2.1 创建密封类


sealed class ColorSealed{
    //以下都是密封类的子类
    //使用object用的是单例,因为下面两个子类没有属性,不管生成多少次都一样
    object Blue : ColorSealed()
    object Yellow : ColorSealed()
    //这个子类有属性,可能属性不同,所以要生成不同的对象
    class Red(val toast:String) : ColorSealed()
}


2.2 使用


       使用密封类的关键好处在于使用 when 表达式的时候,如果能够 验证语句覆盖了所有情况,就不需要为该语句再添加一个 else 子句了。


1.class TakeColorSealed(var colorSealed: ColorSealed) {
    fun selectColor(): String {
        return when (colorSealed) {
            is ColorSealed.Blue -> "蓝色"
            is ColorSealed.Yellow -> "黄色"
            is ColorSealed.Red ->
                "红色,${(this.colorSealed as ColorSealed.Red).toast}"
            //不再需要 else 子句,因为我们已经覆盖了所有的情况
        }
    }
}
fun main() {
    println(TakeColorSealed(ColorSealed.Blue).selectColor())
    println("----------")
    println(TakeColorSealed(ColorSealed.Red("警告警告!!!")).selectColor())
}


这里跟枚举类的使用不太一样。用到了 is 关键字


       调用红色提示的时候将当前的ColorSealed转换为ColorSealed.Red,因为编译时也不知道你传入的是Red还是其他的。



相关文章
|
1月前
|
缓存 API Android开发
Android经典实战之Kotlin Flow中的3个数据相关的操作符:debounce、buffer和conflate
本文介绍了Kotlin中`Flow`的`debounce`、`buffer`及`conflate`三个操作符。`debounce`过滤快速连续数据,仅保留指定时间内的最后一个;`buffer`引入缓存减轻背压;`conflate`仅保留最新数据。通过示例展示了如何在搜索输入和数据流处理中应用这些操作符以提高程序效率和用户体验。
33 6
|
1月前
|
Kotlin
Kotlin 面向对象编程 (OOP) 基础:类、对象与继承详解
面向对象编程(OOP)是一种编程范式,它通过创建包含数据和方法的对象来组织代码。相较于过程式编程,OOP 提供了更快更清晰的结构,有助于遵守 DRY(Don&#39;t Repeat Yourself)原则,使代码更易于维护和扩展。在 Kotlin 中,类和对象是 OOP 的核心。类作为对象的模板,定义了对象的行为和状态;对象则是类的具体实例。例如,`Car` 类可以定义汽车的品牌、型号等属性,以及如驾驶和刹车等功能。通过构造函数可以快速初始化对象的属性。此外,Kotlin 支持继承机制,子类可以从父类继承属性和方法,促进代码重用。
29 2
|
14天前
|
设计模式 安全 编译器
Kotlin 中的密封类:详解与应用
【8月更文挑战第31天】
34 0
|
14天前
|
设计模式 安全 数据库连接
|
14天前
|
存储 前端开发 编译器
深入理解Kotlin中的数据类及其应用
【8月更文挑战第31天】
8 0
|
1天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
7 1
|
1月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
37 4
|
2月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
93 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
2月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin中常见作用域函数
**Kotlin作用域函数概览**: `let`, `run`, `with`, `apply`, `also`. `let`安全调用并返回结果; `run`在上下文中执行代码并返回结果; `with`执行代码块,返回结果; `apply`配置对象后返回自身; `also`附加操作后返回自身
38 8
|
2月前
|
安全 Java Android开发
探索Android应用开发中的Kotlin语言
【7月更文挑战第19天】在移动应用开发的浩瀚宇宙中,Kotlin这颗新星以其简洁、安全与现代化的特性,正迅速在Android开发者之间获得青睐。从基本的语法结构到高级的编程技巧,本文将引导读者穿梭于Kotlin的世界,揭示其如何优化Android应用的开发流程并提升代码的可读性与维护性。我们将一起探究Kotlin的核心概念,包括它的数据类型、类和接口、可见性修饰符以及高阶函数等特性,并了解这些特性是如何在实际项目中得以应用的。无论你是刚入门的新手还是寻求进阶的开发者,这篇文章都将为你提供有价值的见解和实践指导。