Koltin基础学第四章 类对象和接口

类对象和接口

4.1 定义类继承结构

接口

//声明一个简单的接口
interface Clickable{
    fun click()
    fun showoff() = println("  i am Click") //继承后可以更改实现,也可以省略它
}

interface Focusable{
    fun showoff() = println("  i mClick") //拥有相同的方法实现
    fun setFocus(button: Button){
        println(" i click $button focus")
    }
}

class Button:Clickable,Focusable{
    override fun click() {
        println("Click")
    }
}

报错:必须实现showoff方法错误
使用super

class Button:Clickable,Focusable{
    override fun click() {
        println("Click")
    }

    override fun showoff() {
        // 使用super表明想要调用哪一个父类方法
        super<Focusable>.showoff()
    }
    
}

final ,open ,abstract 修饰符

koltin中类和方法默认是final的,防止出现 “脆弱基类”(对基类的修改会导致子类不正确的行为)发生

open class RichButton : Clickable {
    fun disable() {} //这个函数是final,不能在子类中重写
    open fun animate() {} // 这个函数是open 可以在子类中重写
    override fun click() {//没有final的override是open的
    }
}

abstract
abstract class Animation { // 这个类是抽象的,不能创建它的实例
    abstract fun animate() // 这个函数是抽象的 没有实现,必须被子类重写

    open fun stopAnimating() {} // 抽象类不是默认open 但可以标注为open

    fun animateTwice() {}
}

class An : Animation(){
    override fun animate() {
        
    }
}
public
修饰符类成员顶层声明
public(默认)所有地方可见所有地方可见
internal模块中可见模块中可见
protected子类中可见
private类中可见文件中可见
internal open class TalkativeButton : Focusable{
    private fun yell() = println("yell")
    protected fun whisper() = println("let is talk")
}
fun TalkativeButton.giveSpeech(){
    /*
    yell 方法的可见性:private 可见性意味着 yell 方法只能在 TalkativeButton 类的内部访问,不能在扩展函数 giveSpeech 中访问。
    whisper 方法的可见性:protected 可见性意味着 whisper 方法只能在 TalkativeButton 类及其子类内部访问,不能在扩展函数 giveSpeech 中访问。
    在 Kotlin 中,扩展函数并不是真正修改了类的定义,而是像一个静态函数一样被调用。因此,扩展函数无法访问类的私有成员或受保护成员(除非是在子类中)。
     */
}

报错:
在这里插入图片描述

可以将方法修改为public 或者在内部定义方法
internal open class TalkativeButton : Focusable {
    public fun yell() = println("yell")  // 改为 public
    public fun whisper() = println("let's talk")  // 改为 public
}

fun TalkativeButton.giveSpeech() {
    yell()
    whisper()
}

internal open class TalkativeButton : Focusable {
    private fun yell() = println("yell")
    protected fun whisper() = println("let's talk")

    // 在类内部定义扩展函数
    fun giveSpeech() {
        yell()
        whisper()
    }
}

内部类和嵌套类

内部类
interface State:Serializable

interface  ViewS {
    fun getCurrentState(): State
    fun resetCurrentState( state: State){}
}
class Buttons :ViewS{
    override fun getCurrentState(): State = ButtonsState()
    override fun resetCurrentState( state: State){}
    class ButtonsState:State{}// 类似于java中静态嵌套类
}
类A在类B中声明在java中在kotlin中
嵌套类(不存储外部类的引用)static class Aclass A
内部类(存储外部类的引用)class Ainner class A
class Outer{
    // 引用外部类实例,使用this@Outer从inner类中去访问Outer类
    inner class Inner{
        fun getOuter() :Outer = this@Outer
    }
}
密封类

在 Kotlin 中,密封类(sealed class)是一种特殊的类,它用来表示受限的类层次结构。密封类的子类必须嵌套在密封类中,或者与密封类在同一个文件中定义。这使得密封类非常适合表示有限的、明确的类型集,通常用于表示有限的状态集或结果类型。

使用密封类的场景
  1. 表示状态或结果类型:密封类常用于表示一组有限的可能状态。例如,网络请求的结果可能是成功、失败或进行中。

  2. 简化 when 表达式:在处理密封类的子类时,when 表达式可以确保所有可能的子类都得到了处理,从而避免遗漏某些情况。

  3. 处理错误或异常:密封类可以用于表示一组有限的错误类型,这样可以在处理错误时提供更好的类型安全性。

1. 表示网络请求的结果
sealed class Result {
    data class Success(val data: String) : Result()
    data class Failure(val error: Exception) : Result()
    object Loading : Result()
}

fun handleResult(result: Result) {
    when (result) {
        is Result.Success -> println("Data: ${result.data}")
        is Result.Failure -> println("Error: ${result.error.message}")
        is Result.Loading -> println("Loading...")
    }
}
2. 表示有限状态的状态机
sealed class UiState {
    object Loading : UiState()
    data class Success(val data: List<String>) : UiState()
    data class Error(val message: String) : UiState()
}

fun render(state: UiState) {
    when (state) {
        is UiState.Loading -> println("Loading...")
        is UiState.Success -> println("Data: ${state.data}")
        is UiState.Error -> println("Error: ${state.message}")
    }
}
3. 处理错误类型
sealed class ErrorType {
    object NetworkError : ErrorType()
    data class ServerError(val code: Int) : ErrorType()
    object UnknownError : ErrorType()
}

fun handleError(error: ErrorType) {
    when (error) {
        is ErrorType.NetworkError -> println("Network error occurred")
        is ErrorType.ServerError -> println("Server error with code: ${error.code}")
        is ErrorType.UnknownError -> println("Unknown error occurred")
    }
}
使用密封类的优点
  1. 类型安全:密封类提供了类型安全性,确保所有可能的类型都被显式处理。
  2. 易于维护:由于密封类的子类必须在同一文件中定义,因此很容易查看和维护所有可能的子类。
  3. 简化 when 表达式:在 when 表达式中处理密封类时,如果遗漏了某个子类,编译器会发出警告,从而减少错误。
总结

密封类在 Kotlin 中非常适合用于表示有限的状态集或结果类型,可以提高代码的类型安全性和可维护性。在需要处理一组有限的、不变的可能状态或结果时,密封类是一个强大的工具。

4.2 声明带非默认构造方法或属性的类

class User(val email: String) //声明一个简单类

class Main(){
    fun main(args: Array<String>){
        //创建实例只需要调用构造方法,不需要new关键字
        val alice = Users("Alice",false)
        println(alice.isSub)
    }
}

class Users constructor (private val _email: String, val isSub :Boolean = true){ // constructor 用于开始一个主构造方法或从构造方法的声明
    val email : String = _email // init 用于引入一个初始化语句块
}

// 声明一个不带主构造方法,有从构造方法的类
open class View {
    constructor(ctx :Context){

    }

    constructor(ctx :Context,att:AttributeSet){

    }
}

class MyButton : View {
    constructor(ctx :Context):this(ctx = ctx){
        println()
    }

    constructor(ctx: Context,att: AttributeSet):super(ctx, att){

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值