kotlin筑基(2)

一、internal

internal 修饰方法,表示这个方法只适合当前 module 使用,同理修饰 class 也是一样。

@Synchronized internal fun executed(call: RealCall) {
    runningSyncCalls.add(call)
}

二、infix

2023-7-7 11:01:19

Kotlin允许在不使用括号和点号的情况下调用函数,那么这种函数被称为 infix函数(中缀函数)。

定义 infix 函数,需要满足以下要求

  1. 它们必须是成员函数或扩展函数
  2. 它们必须只有一个参数;
  3. 其参数不得接受可变数量的参数且不能有默认值
class Util(val number:Int) {
    infix fun sum(other: Int) {
      println(number + other)
   }
}

fun main(){
    val u = Util(5)
 
    u sum 5 //  10
    u sum 7 // 12
}

请注意,中缀函数总是要求指定接收者与参数。当使用中缀表示法在当前接收者上调用方法时,需要显式使用 this;不能像常规方法调用那样省略

class MyStringCollection {
    infix fun add(s: String) { /* …… */ }
    
    fun build() {
        this add "abc"   // 正确
        add("abc")       // 正确
        add "abc"        // 错误:必须指定接收者
    }
}

中缀函数与操作符的优先级

  1. 中缀函数调用的优先级低于算术操作符、类型转换以及 rangeTo 操作符

    1 shl 2 + 3  等价于         1 shl (2 + 3)
    0 until n * 2 等价于        0 until (n * 2)
    xs union ys as Set<*>  等价于  xs union (ys as Set<*>)
    
  2. 中缀函数调用的优先级高于布尔操作符 && 与 ||、is- 与 in- 检测以及其他一些操作符

    a && b xor c  等价于   a && (b xor c)
    a xor b in c  等价于  (a xor b) in c
    

三、object

类和对象同时创建,相当于 懒汉式单例,里面的方法是 final 方法

  1. val 变量相当于 private static final
  2. var 变量相当于 private static

kotlin中有四种方式表示静态:

  1. object单例类模式
  2. companion object
  3. JvmStatic注解模式
  4. 顶层函数模式

object:反编译java代码是由一个静态类包含一系列非静态函数

companion object:同上

JvmStatic:只能注解在单例或companion object 中的方法上,反编译java代码是一个静态函数

顶层函数:反编译java代码是一个静态函数


四、open

2023-7-7 09:51:24

在java中允许创建任意的子类并重写任意的方法,除非显示的使用了final关键字进行阻止。

而在kotlin的世界里面则不是这样,在kotlin中它所有的类默认都是 final的,那么就意味着不能被继承,而且在类中所有的方法也是默认是final的,那么就是kotlin的方法默认也不能被重写,所以open 关键字就是用来解决这个现象的。


五、operator

2023-1-16 14:00:13

operator:重载修饰符。重载运算符以达到修改原有的运算逻辑输出调用者需要的结果

常见的运算符

运算符运算重载表示
a+ba.plus(b)
a-ba.minus(b)
a*ba.times(b)
a/ba.div(b)
a%ba.rem(b) 或 a.mod(b)
a…ba.rangeTo(b)
++a, a++inc
!anot
a>ba.compareTo(b)>0
a<ba.compareTo(b)<0
a<=ba.compareTo(b)>=0
a<=ba.compareTo(b)<=0
a in bb.contains(a)
a !in b!b.contains(a)

重载plus

比如上面的 a+b,我们在使用时候除了使用这种方式还可以使用运算重载表示a.plus(b),但是需要提前定义好函数

// 一定要使用 operator 修饰 plus 函数,否则无法使用 + 号
class My(val a:Int){
    operator fun plus(b:Int):Int{
        return a*b // 也可以使用 a.times(b) --> kotlin默认运算符重载表示(Primitives.kt)
    }
}

// 使用
fun main(){
    val a = My(3)
    val plus = a.plus(3)

    val i = a + 4
    println(i)
    println(plus) 
    // 输出
    // 12, 9
}

重载get

operator除了可以重载运算符号,还可以重载get

class My(val a:Int){
    val arr = mutableListOf(1,2,3,4)
   
    operator fun get(index:Int):Int{
        return arr[index+1]
    }
}
// 使用
fun main(){
    val a = My(3)
    val get = a.get(0)// 也可以是 val get = a[0]
    println(get)
    // 输出 2
}

六、sealed class

2023-7-19 16:54:58

sealed class,密封类。具备最重要的一个特点:

其子类可以出现在定义 sealed class 的不同文件中,但不允许出现在不同的 module 中,且需要保证 package 一致。这样既可以避免 sealed class 文件过于庞大,又可以确保第三方库无法扩展你定义的 sealed class,达到限制类的扩展目的。

1. 用法一

是一个有特定数量子类的类,看上去和枚举有点类似。

 // TestSealed.kt
 sealed class GameAction(times: Int) {
     // Inner of Sealed Class
     object Start : GameAction(1)
     data class AutoTick(val time: Int) : GameAction(2)
     class Exit : GameAction(3)
 }

//与内部类的创建一样
fun main(args:Array<String>){
    var sc:GameAction = GameAction.Start()
}

2. 用法二

2023-11-21 星期二

可以实现普通类无法实现的 条件判断语句

sealed class Result
class Success(val code: Int) : Result()
class Exception(val code: Int, val message: String) : Result()

fun handleResult(result: Result): String{
    return when(result) {
        is Success -> {
            "success"
        }
        is Exception -> {
            "exception"
        }
    }
}

反编译后的java代码,Result 类其实是一个抽象类,SuccessException 继承了这个抽象类。Result 类的构造函数是私有的,不能在外部访问到。

通过继承这个抽象类,达到限制类型的做法。

这其实和 java 中使用接口来限定参数类型的做法类似,很好理解。


七、typealias

2023-10-27 20:34:13

别名。和 import as 很像,但两者使用范围有差别,具体查看链接。

  • typealias 只能定义在顶层位置,不能被内嵌在类、接口、函数等内部(import as)。

kotlin中的别名:

@SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E>
@SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>
@SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V>
@SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
@SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E>

多数通用场景:

// Classes and Interfaces (类和接口)
typealias RegularExpression = String
typealias IntentData = Parcelable
 
// Nullable types (可空类型)
typealias MaybeString = String?
 
// Generics with Type Parameters (类型参数泛型)
typealias MultivaluedMap<K, V> = HashMap<K, List<V>>
typealias Lookup<T> = HashMap<T, T>
 
// Generics with Concrete Type Arguments (混合类型参数泛型)
typealias Users = ArrayList<User>
 
// Type Projections (类型投影)
typealias Strings = Array<out String>
typealias OutArray<T> = Array<out T>
typealias AnyIterable = Iterable<*>
 
// Objects (including Companion Objects) (对象,包括伴生对象)
typealias RegexUtil = Regex.Companion
 
// Function Types (函数类型)
typealias ClickHandler = (View) -> Unit
 
// Lambda with Receiver (带接收者的Lambda)
typealias IntentInitializer = Intent.() -> Unit
 
// Nested Classes and Interfaces (嵌套类和接口)
typealias NotificationBuilder = NotificationCompat.Builder
typealias OnPermissionResult = ActivityCompat.OnRequestPermissionsResultCallback
 
// Enums (枚举类)
typealias Direction = kotlin.io.FileWalkDirection
// (but you cannot alias a single enum *entry*)
 
// Annotation (注解)
typealias Multifile = JvmMultifileClass

八、when

2024-1-5 16:46:17 星期五

1. 带参数

fun mix(color1: ColorEnum, color2: ColorEnum) =
    when(setOf<ColorEnum>(color1, color2)){
        setOf(ColorEnum.RED, ColorEnum.GREEN) -> "黄色"
        setOf(ColorEnum.RED, ColorEnum.BLUE) -> "紫色"
        setOf(ColorEnum.BLUE, ColorEnum.GREEN) -> "黑色"
        else -> throw Exception("不知道什么颜色")
}

2. 不带参数

带参数的会好理解一些,根据when的条件去做判断,最终给出符合条件的输出。但是不带参数的,我们做了验证,结果如下:谁先成立执行谁,并跳出判断。

class CustomBean{
  val conditon1=true
  val conditon2=true
  val conditon3=false
}

fun main(){
  	val cb = CustomBean()

    when{
        cb.conditon1-> l2.i("Splash","conditon1")
        cb.conditon2-> l2.i("Splash","conditon2")
        else-> l2.i("Splash","else")
    }  
}

/*输出:
conditon1
*/

看下反编译后的java代码,所以相当于 if else ,谁先成立执行谁,并跳出判断。

public static void main(String[]args){
    CustomBean cb = new CustomBean();
      if (cb.getConditon1()) {
         l2.i("Splash", "conditon1");
      } else if (cb.getConditon2()) {
         l2.i("Splash", "conditon2");
      } else {
         l2.i("Splash", "else");
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值