sisterofDC / kotlin_study

0 stars 0 forks source link

study for kotlin #1

Open sisterofDC opened 3 years ago

sisterofDC commented 3 years ago

创建新的项目 一 更新app目录下的build.gradle 在MainActivity onCreate() 加入 log.d("MainActivtiy","onCreate exectue") 在线编写kotlin 的代码https://try.kotlinlang.org

sisterofDC commented 3 years ago

变量 变量申请 Var 变量名:类型 = [] Java 中的类型都相当于大写 int Int long Long short Short float Float double Double boolean Boolean char Char byte Byte list List set Set map Map 比较重要的几个 Int Double Boolean List Set Map

sisterofDC commented 3 years ago

var 可以变的变量 val 只读变量

sisterofDC commented 3 years ago

if/else if range 表达式 range A..B是否检查在指定范围 when 改写else if 语句 const val Max = 200 const val Min = 100 fun main() { var middle="middle" var a:Int = 150 if(a>Max){ println("big") }else if(a<Min){ println("small") } /fun function_range(number:Int)/ if(a in Min..Max){ println(middle) }

}

sisterofDC commented 3 years ago

when的使用

const val Max = 200 const val Min = 100 fun main() { var number:Int = 200 var result:String =when(number){ Max -> "big" Min -> "small" else -> "0" } println(result) } 现在好像只能写一个精准的匹配,它会把when的匹配值返回

如果想写一个when中还有判断语句 const val Max = 200 const val Min = 100 fun main() { var number:Int = 200 var result:String result= when(number){ in Min..Max -> "middle" /相当于nunber>=Min&&number<=Max/ !in Min..Max -> "out of range" else -> "edge" } println(result) }

sisterofDC commented 3 years ago

字符串中加入符号${} const val name = "sisterofDC" fun main(){ var sex:String ="boy" println("$name is $sex") }

sisterofDC commented 3 years ago

kotlin中函数 fun main(){ println(function_test(5,"wang")) }

public fun function_test(name:Int,sex:String):String{ val result ="sisterofDC is boy" return result } 简单的列子 反引号可以用于特别的函数,可以避免所有的冲突

sisterofDC commented 3 years ago

fun main(){ println(function_test(5,"wang")) function_test_two("wang") var whole_name =function_test_three(name="wang",sex="man",study="collage",age=20,intro="sister") /具名的函数参数,可以不和函数的参数名一样/ println(whole_name) println(function_test_two("a")) }

public fun function_test(name:Int,sex:String):String{ val result ="${name} is ${sex}" return result }

private fun function_test_two(name:String,age:Int=2){ println(name+age) }

public fun function_test_three(name:String,sex:String,age:Int,intro:String,study:String):String{ val result ="${name} ${sex} ${intro} ${age} ${study}" return result }

/unit函数 TODO????/ /5 is wang wang2 wang man sister 20 collage a2 kotlin.Unit/

sisterofDC commented 3 years ago

匿名函数 val result_one = "abcjd".count() println(result_one)

如果改为匿名函数

首先count()函数中 对比的 是字符 不是字符串 所有用的是‘’ 不是”“ 那么如果想找到相同的

val result_one = "abcjd".count({ a-> a== 'a' }) println(result_one)

将变量写为隐函数的方法

如果是简写

result_one.count{it=='a'}

参考声明变量 var 变量名 : ([缺省参数类型])-> 返回类型={ [参数类型]->

}

var result_two :(Int)->String ={number->
    val a=1
    "$number+$a"
}
println(result_two(1))
sisterofDC commented 3 years ago

简单的介绍音乐

`fun main(){

val musicname ="the is the dream"
var show_the_deteils:(String,Double)->String={singer:String,song_length:Double ->
    var whole ="${singer} ${song_length}"
    "${whole}"
}
val final=show_the_intro(musicname,show_the_deteils)
println(final)

}

fun show_the_intro(musicname:String,show_the_deteils:(String,Double)->String):String{ val singer ="sisterofDC" val song_length= 3.57 val whole="${musicname}+${show_the_deteils(singer,song_length)}" return whole }`

the is the dream+sisterofDC 3.57 这里是用函数调用函数的方法

sisterofDC commented 3 years ago

如果是函数的引用的写法 `fun main(){ val musicname:String ="this is the dream" val final= show_the_intro(musicname,::show_the_deteils) println(final) }

private fun show_the_deteils(singer:String,song_length:Double):String{ val whole ="${singer} ${song_length}" return whole }

private fun show_the_intro(musicname:String,show_the_deteils:(String,Double)->String):String{ val singer ="sisterofDC" val song_length= 3.57 val whole="$musicname+${show_the_deteils(singer,song_length)}" return whole }`

这里看到如果需要传入一个函数 用的的是::

sisterofDC commented 3 years ago

理论上来说,这个相当于重修学习java。android真正的开发还没有开始

sisterofDC commented 3 years ago

fun main(){ val song ="this is a dream"

val get_song= singersong(song){singer:String,song_length:Double,intro:String-> "${singer} ${song_length} ${intro}" }/这里相当于直接闭包写了一个,sing_deteail/

println(get_song) }

private fun singersong(sing_name:String,sing_deteail:(String,Double,String)->String):String{ val singer ="sisterofdc" val song_length = 3.14 val intro = "this is a backgroudmusic" return "${sing_name} ${sing_deteail(singer,song_length,intro)}" }

当然闭包函数还有更多的应用的,这里就写一下

sisterofDC commented 3 years ago

fun main(){ var is_this_NULL:String? ="sisterofDC" is_this_NULL=null println(is_this_NULL) }

kotlin 解决了空指针的问题

如果要用空指针的判断 !!. ?.

变量 ?: 值 如果变量为空,就为右边的值 当然也可以为语句

kotlin也要需要空指针抛出

sisterofDC commented 3 years ago

字符串的操作 首先是until 语法结果为 substring(/range/ until index) 接着是分割 split 返回的是一个list const val song = "this is the dream,rain,bad apple" val songs = song.split(',') println(songs) [this is the dream, rain, bad apple]

接着是repalce fun CharSequence.replace( regex: Regex, replacement: String ): String (source)

标准格式 regex为正则表达式 列子

const val song = "this is the dream,rain,bad apple"
    val str1 = song.replace(Regex("[abc]")){
        when(it.value){
            "a" -> "1"
            "b" -> "2"
            "c" -> "3"
            else -> it.value
        }
    }
this is the dre1m,r1in,21d 1pple
sisterofDC commented 3 years ago

== 和 === 前一个比的是内容 后面相当于比的是指针地址

sisterofDC commented 3 years ago

apply let 返回最后一行 run 返回true or false
支持链式调用 with(){}传入括号中的参数

fun main(){
    var test_one="this is the dream "
    var fileContent:List<String>
    var pathname="C://Users//WYX//Documents/test.txt"
    File(pathname).let {
        it.writeText(test_one)
        fileContent =it.readLines()

    }
    println(fileContent)
}

结果为this is the dream also函数和let函数功能相似。also也是吧接受者作为值参传给lambda。但有一点不同 also返回接收者对象
let返回lambda结果

看对比

fun main(){
    var test_one="this is the dream "
    var pathname="C://Users//WYX//Documents/test.txt"
    var result = File(pathname).also {
        it.writeText(test_one)
        it.readLines()

    }
    println(result)
}

返回的结果为 C:\Users\WYX\Documents\test.txt 即接收者对象

kotlin写入文件

package com.zetcode

import java.io.File

fun main() {

    val fileName = "src/resources/myfile.txt"
    val myfile = File(fileName)

    myfile.printWriter().use { out ->

        out.println("First line")
        out.println("Second line")
    }

    println("Writed to file")
}
sisterofDC commented 3 years ago

take if takelf函数需要判断lambda中提供的条件表达式,给出true或false结果,如果判断结果是true,从takelf函数返回接收者对象,如果是false,则返回null。如果需要判断某个条件是否满足,再决定是否可以赋值变量或执行 某项任务,takelf就非常有用,概念上讲,takelf函数类似于if语句,但它的优势是可以直接在对象实例上调用,避免了临时变量赋值的麻烦。

sisterofDC commented 3 years ago

List,Set,Map的应用

sisterofDC commented 3 years ago

listOf是不可变列表

var mutableList = mutableListOf<String>("1","2","3") 当然可变列表也可以变成不可变列表

fun main() {

    val mutableList = mutableListOf<Int>(123,2456,327)
    mutableList += 2
    mutableList.add(8923)
    mutableList.remove(2)
    println(mutableList)
}

+= add() remove removeif(it.contains())

list的遍历方式

fun main() {
    val mutableList_one = mutableListOf<String>("wangjinxiang","wangyixin","sisterofDC")
    mutableList_one.forEach{
        println(it)
    }

    mutableList_one.forEachIndexed{index, s ->
        println("${index} $s")

    }
}
sisterofDC commented 3 years ago

set 不能有重复的元素

list 可以有重复的元素 当然set 中也有Listz中的函数使用

fun main() {
    val mutableSet_one = mutableSetOf<String>("wangjinxiang","wangyixin","sisterofDC")
    /*安全的访问)/

     */
    mutableSet_one.add("thisistest")
    mutableSet_one += "thisistwotest"

    mutableSet_one.removeIf{it.contains("a")}

    val result=mutableSet_one.elementAtOrNull(2)
    println(result)
    mutableSet_one.forEach{
        println(it)
    }
}

set 和list 可以互相转化 var mutableSet_two= mutableSet_one.toMutableList() 如果仅是想list 去掉重复的元素 可以用 mutableSet_two.distinct()

sisterofDC commented 3 years ago

Map 的基本学习


fun main(){

    /*kotlin中to是返回一个pair 类型 */
    val map_one:Map<String,Int> = mapOf("sister" to 1,"of" to 2 ,"DC" to 3)
    /*所有可以直接用一对键值来创建*/
    val map_two = mapOf(Pair("wangyixin", 20), Pair("abc", 2))

    println(map_one["sister"])//直接传键值
    println(map_two.getValue("abc"))
    val result= map_one.getOrDefault("of",0)
    val result_one = map_one.getOrElse("dc"){"this is no element"}

    /*键值的遍历 传入it的参数 */
    map_one.forEach{
        println("${it.key} ${it.value}")
    }
    /*键值的遍历 传入复写函数 */
    map_two.forEach{(key:String,value:Int) ->
        println("${key} ${value}")
    }

}
sisterofDC commented 3 years ago

可变的Map


fun main() {
    val mutableMap_one = mutableMapOf<String,Int>("a" to 1,"b" to 2, "c" to 3)

    mutableMap_one += "d" to 4

    mutableMap_one.put("e", 5)

    mutableMap_one.getOrPut("g"){6}

    mutableMap_one.forEach{
        println("${it.value} ${it.key}")
    }

}
sisterofDC commented 3 years ago

类的学习

class player {
    var name:String? ="jack"
        /*如果想要变成可空的,就要用!!。*/
    get() = field!!.toUpperCase()
        /*当然不能对空的进行大小写*/
    set(value){
        if (value!=null){
            field=value.capitalize().trim()
        }else{
            field=value
        }
    }

}

fun main() {
    /*申请一个类的对象*/
    val player_one =player()

    println(player_one.name)
    player_one.name="  abc bcd "
    println(player_one.name)
}

class player {
    var name:String? ="jack"
        /*如果想要变成可空的,就要用!!。*/
    get() = field!!.toUpperCase()
        /*当然不能对空的进行大小写*/
    set(value){
        if (value!=null){
            field=value.capitalize().trim()
        }else{
            field=value
        }
    }

    /*也可以直接复写get*/
    var number_one =(1..10).shuffled().first()

    var intro:String? = "mywork"
    /*如果是有空的变量,则必须要使用空安全符号?。*/
    fun putintro():String?{
        intro=intro?.let {
            println("${it}")
            it.toUpperCase()
        }
        return intro
    }

}

fun main() {
    /*申请一个类的对象*/
    val player_one =player()

    println(player_one.name)
    player_one.name="  abc bcd "
    println(player_one.name)

   val result =player_one.putintro()
    println("${result}")

}
sisterofDC commented 3 years ago

kotlin中 在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。主构造函数是类头的一部分:它跟在类名(与可选的类型参数)后。

主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中。

如果不加入Init的模块,则在次级构造中回直接报错 Expecting member declaration


class song( var name:String, var singer:String,var length:Double){
    init {
        this.name=name.toUpperCase()
    }
    constructor(name:String):this(name,singer = "sisterofDC",length=0.00){
        this.name=name.toLowerCase()
    }
    constructor(length: Double):this(name="unkown",singer="unkown",length){
        this.name=name.toLowerCase()
        this.length=3.00+length
    }

}

fun main() {

    val song_one =song("abcde","sisterofdc",3.0)
    val song_two =song(1.0)
    println("${song_one.name} ${song_one.singer} ${song_one.length}")
    println("${song_two.name} ${song_two.singer} ${song_two.length}")
}

结果 ABCDE sisterofdc 3.0 unkown unkown 4.0

sisterofDC commented 3 years ago

类的初始化顺序

主构造函数里声明的属性 类级别的属性赋值 init初始化块里的属性赋值和函数调用 次构造函数里的属性赋值和函数调用

lateinit 用:: isInitialized来进行检查

/惰性初始化/ val config by lazy { loadconfig() } private fun loadconfig() :String{ println("this is loading") return "plasewait" }

如果不去调用config就不会调用函数

sisterofDC commented 3 years ago

继承和复写

在kotlin中如果想要继承类,必须加上open 关键字 想复写函数,也要加上open

可以用is 来检测对象的类型 使用as 来进行类型转换

open class Pruduct (var name:String,var Id:Int){
    open fun showpruduct(){
        println("${name} ${Id}")
    }
}

class betterPruduct:Pruduct("betterproduct",100){
    override fun showpruduct() {
        println("this is better pruduct ${name} ${Id}")
    }
}

fun main(){
    val a:Pruduct =betterPruduct()
    a.showpruduct()
    println(a is Pruduct)
    println(a is betterPruduct)
   /*前提式用val a :Pruduct*/
    println((a as betterPruduct).thisisspecail())

}

any是所有类的超类

sisterofDC commented 3 years ago

object 可以定义一个只能产生一个实列的类-单列 对象声明 对象表达式 伴生对象

import java.io.File
class any (var a: Int,var b: Int){
    fun divide(a: Int,b: Int):Int=a-b
}

open class test(var name:String,var age:Int){
    open fun thisistest() ="这是一个类"
    val adult=18
    open fun muti(b:Int,a:Int) :Int{
        return a*b
    }

}

object androidinit{ /*声明一个对象*/
    init {
        println("this is object")
    }

    fun add(a:Int,b:Int):Int{
        return a + b
    }
}
/*如果想某个对象初始化和一个类实列捆绑一起,用companion。一个类只能有一个伴生对象*/

/*static在kotlin中的实现*/

open class readfile{
    //static
    init {
        println("this is file reading")
    }
    companion object{
        private  const val PATH="C://Users/WYX/Documents/test.txt"
        open fun print() {
            val file=File(PATH).readText()
            println(file)
        }
    }
}

fun main() {

    val test=any(1,2)
    val c=androidinit.add(test.a,test.b)
    val d=test.divide(test.a,test.b)
    val e=object :test("sisterofdc",20){  /*这里直接申请了一个对象,只有这个一个对象,不能连续申请*/
        override fun thisistest(): String {
            return "这是一个对象"
        }
    }
    println("${c}   ${d}  ${e.thisistest()}  ${e.muti(e.age,e.adult)}")

    /*只有在调用readfile这个函数的时候才会实列化,伴随对象*/
    readfile.print()
}
sisterofDC commented 3 years ago
class inner {
    /*如果一个类只对另一个类有用,那么将其嵌入到该类中并使这两个类保持在一起是合乎逻辑的,可以使用嵌套类*/
    class thisisinnerclass(var element:String){
        fun use(){
            println("this is innerclass ${element}")
        }
    }
}
/*数据类 数据类至少有一个参数 不能用abstract ,open ,sealed inner 的修饰符*/
 data class thisisdataclass(var getelementid:String,var colors:String,var longth:Int){
    private val contant="this is text"
    var width =20
     fun print():String{
         return "${this.getelementid},${this.colors}"
     }

    override fun toString(): String {
        return "thisisdataclass(getelementid='$getelementid', colors='$colors', longth=$longth, contant='$contant', width=$width)"
    }

    constructor(getelementid: String):this(getelementid,colors="red",longth=2){
        width=10
    }

 }

/*数据类提供了equals hashcode tostring copy的个性化实现 它会自动为所有定义在主构造函数的属性添加组件函数*/
/*在copy函数中,会重新new 对象出来,不会去调用constructor的方法*/
//thisisdataclass(getelementid='text', colors='red', longth=2, contant='this is text', width=20)
//thisisdataclass(getelementid='button', colors='red', longth=2, contant='this is text', width=20)

fun main() {
    inner.thisisinnerclass("sisterofdc").use()
    val a=thisisdataclass("text","red",2)
    println(a)
    val b=a.copy("button")
    println(b)
    /*数据类本身具有解构函数*/
    val (element_one,element_two,element_three)=thisisdataclass("text","red",2)
    println("$element_one,$element_two,$element_three")
}
sisterofDC commented 3 years ago

常见的运算符重载

sisterofDC commented 3 years ago

枚举类的简单应用

enum class ispay{
    FREE,
    VIP,
    PAYING;
}

class song(var status:ispay){
    fun song_ispay():Int{
        return when(status){
            ispay.FREE -> 1
            ispay.PAYING ->0
            ispay.VIP ->-1
        }
    }
}

fun main() {
    println(song(ispay.VIP).song_ispay())
}
sisterofDC commented 3 years ago

封装类


sealed class song {
    object FREE:song()
    object VIP:song()
    class PAYING(val payid:String):song()
}

class sealedclass (var test: song){
    fun test_song():String{
        return when(test){
            is song.FREE -> "免费"
            is song.VIP -> "VIP"
            is song.PAYING -> "付费歌曲 单号${(this.test as song.PAYING).payid}"
        }
    }
}

fun main() {
    val song_one = song.PAYING("123")
    val song_two = song.FREE

    println(sealedclass(song_one).test_song())
    println(sealedclass(song_two).test_song())
}

结果 付费歌曲 单号123 免费

sisterofDC commented 3 years ago

interface 接口类,在实现接口的时候必须实列化对象。即写出get 和 set

interface song_intro{
    var name:String
    var length:Double
    var singer:String
    fun intro(var lable_list:List):String
}

class song ( ):song_intro{
    override var name: String
        get() = TODO("Not yet implemented")
        set(value) {}
    override var length: Double
        get() = TODO("Not yet implemented")
        set(value) {}
    override var singer: String
        get() = TODO("Not yet implemented")
        set(value) {}

    override fun intro(lable_list: ???): String {
        TODO("Not yet implemented")
    }
}

fun main() {

}
sisterofDC commented 3 years ago
import java.time.Year

//多重继承
class abstractclass {
}

//泛型 单反向参数
class test<T>(element:T){
    var avilable = false
    private var contants =element
    fun test(element: T):String{
        return when(element){
            is String ->"这是个字符串"
            is Int ->"这是个整数"
            is Double ->"这是个浮点数"
            else ->"未知"
        }
    }
    fun get():T?{
        return contants.takeIf { avilable }
    }

}

//多泛型参数

data class boy(var name:String,var age:Int){

}

class girl(var name:String,var intro:String)

fun main() {
    val boy1=test(boy("sisterofdc",20))
    boy1.avilable =true
    println(boy1.get())
}

问题 1.泛型中,如何重载运算符 2.多个泛型参数如果进行编写 3.泛型的应用,比如进行类的转换,如song class -> song_lable class 的转换

sisterofDC commented 3 years ago

父类泛型对象可以赋值给子类泛型对象,用in 子类泛型对象可以赋值给父类泛型对象,用out

sisterofDC commented 2 years ago

javascript中修改prototype就可以扩展函数 在kotlin中。如果无法接触某课类的定义。或者某个类没有使用open修饰符,导致无法继承它。扩展就是增加类功能的最好的选择

fun String.addmore(times:Int):String{//继承String类,添加一个addmore 函数
    val Max = 10
    var tem:String=this
    when(times){
        in 2..Max ->    repeat(times){tem=tem+"this is test"}
        else -> tem="never changer"
    }
    return tem
}

fun main() {
    var text="sisterofDC"
    text=text.addmore(4)
    println(text)
}

当然也可以继承Any类,就可以任意函数都可以使用

fun Any.println():Any{
    println(this)
    return this
}
sisterofDC commented 2 years ago

用as 进行强制类型转换