Kotlin入门

Kotlin

概述

Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在Google I/O 2017中,Google 宣布 Kotlin 成为Android 官方开发语言。Android Studio 3.0 已经自带Kotlin的插件。
谷歌和 JetBrains 将为 Kotlin 成立一个非盈利基金会。Kotlin 语言的开发,还是 JB 为主导。

基本语法

Kotlin 的基本数值类型包括 Byte、Short、Int、Long、Float、Double、Boolean 等。不同于Java的是,字符不属于数值类型,是一个独立的数据类型。

Int到底是什么?

fun main(args: Array<String>) {

    //final 反编译
    val i = 10 //val 可以理解为java的final 变量

    var j: Int? = null

    var c = '1'

}

class反编译为Java

public static final void main(@NotNull String[] args)
  {
    Intrinsics.checkParameterIsNotNull(args, "args");

    int i = 10;

    Integer j = (Integer)null;

    char c = '1';
  }
条件循环语句
    var a = 10
    var result: Int = if (a > 10)  100 else 1000

    result = when(a) {//when 代替 switch

        1 -> 100

        2 -> {
            100 + 1000
        }
        else -> {
            1 + 2
        }
    }


    val items = listOf("apple", "banana", "kiwi")

    for (item in items) {
        println(item)
    }

    for (i in 1..100) {
        println(i)
    }
类的定义


//定义一个Person类,可以在构造方法里定义成员变量
//?代表变量可null
class Person(val name: String?, val age: Int?)


//定义一个空类
class Person


//私有构造方法   参数默认值  
open class Person(name: String? = "lisi", age: Int? = 10) {

    //次构造函数
    constructor(name: String?, age: Int?, id: String): this(name, age) {
        this.id = id
    }

    //初始化
    init {
        //......
    }

    var name = name
        get() = name + "tail"
        set(value) {
            field = "header" + value
        }
    var age = age

    var id: String? = null


    inner class Sutdent2 {

        init {
            println(name)//读取外部类的成员
        }

    }


    class Student {//嵌套类

        init {
            //println(name) 嵌套类对外部类this没有引用 不能读取成员变量
        }
    }


}



data数据类

data类型的类会帮你自动生成equals、hashCode、toString、copy方法

fun main(args: Array<String>) {

    var comment = Comment("zhangsan", "123456")
    var comment2 = Comment("lisi", "654321")
    println(comment.toString())
    println(comment.equals(comment2))


    //fun copy(name: String = this.name, commentId: String = this.commentId) = Comment(name, commentId) //copy原型
    var comment3 = comment.copy("wangwu")
    println(comment3)
}

data class Comment(var name: String, var commentId: String)

classModifier: 类属性修饰符,标示类本身特性:

  • abstract // 抽象类
  • final // 类不可继承,默认属性
  • enum // 枚举类
  • open // 类可继承,类默认是final的
  • annotation // 注解类

accessModifier: 访问权限修饰符:

  • private // 仅在同一个文件中可见
  • protected // 同一个文件中或子类可见
  • public // 所有调用的地方都可见
  • internal // 同一个模块中可见

object类

单例模式

fun main(args: Array<String>) {
    SingleTest.println()
}

object SingleTest{
    fun println() {
        println("SingleTest")
    }
}

以下为class反编译的java代码


public static final void main(@NotNull String[] args)
  {
    Intrinsics.checkParameterIsNotNull(args, "args");
    SingleTest.INSTANCE.println();
  }


public final class SingleTest
{
  public static final SingleTest INSTANCE;

  static
  {
    new SingleTest();
  }

  private SingleTest()
  {
    INSTANCE = (SingleTest)this;
  }

  public final void println()
  {
    String str = "SingleTest2";System.out.println(str);
  }
}

单例延迟创建对象,companion object处理静态方法和常量

fun main(args: Array<String>) {

    SingleTest.instance.println()

    SingleTest.staticFunction()
}

class SingleTest private constructor() {

    companion object {

        //定义常量
        const val EVENT_INIT = "123"

        val instance: SingleTest by lazy { 
            SingleTest() 
        }

        //类似静态方法
        fun staticFunction() {
            println("staticFunction")
        }

    }

    fun println() {
        println("SingleTest")
    }
}

class反编译为Java


public static final void main(@NotNull String[] args)
  {
    Intrinsics.checkParameterIsNotNull(args, "args");
    SingleTest.Companion.getInstance().println();
    SingleTest.Companion.staticFunction();
  }

public final class SingleTest {
    public static final Companion Companion = new Companion(null);
     @NotNull
    public static final String EVENT_INIT = "123";



    @NotNull
    private static final Lazy instance$delegate = LazyKt.lazy((Function0)SingleTest2.Companion.instance.2.INSTANCE);

    public static
    final class Companion {
        @NotNull
        public final SingleTest getInstance()
        {
            Lazy localLazy = SingleTest . access $getInstance$cp();
            Companion localCompanion = this;
            KProperty localKProperty = $$delegatedProperties[0];
            return (SingleTest2) localLazy . getValue ();
        }

        public final void staticFunction()
        {
            String str = "staticFunction";
            System.out.println(str);
        }
    }

    public final void println()
    {
        String str = "SingleTest";
        System.out.println(str);
    }
}

静态方法和常量完全可以只使用普通函数和const关键字

//Constans.kt 文件
package com.vmovier.promise3.test
const val EVENT_INIT = 1
//Utils.kt 文件
package com.vmovier.promise3.test

import java.text.SimpleDateFormat
import java.util.*

fun formatDate(millTime: Long) {
    var format = SimpleDateFormat("yyyy-MM-dd")
    val date = format.format(Date(millTime))
    println(date)

}
//test.kt 文件
fun main(args: Array<String>) {
    println(EVENT_INIT)
    formatDate(100000)
}

泛型

协变

Java协变

public static void main(String[] args) {

    //java编译器并不认为 
    //ArrayList<String>是ArrayList<Object>的子类
    //下面的代码不能通过编译
    ArrayList<Object> list = new ArrayList<String>();

    //,在java里这两个类没有任何关系,如果让它们有关系可
    //以使用通配符
    ArrayList<? extends Object> list = new ArrayList<String>();

}

Kotlin协变、逆变,Kotlin支持声明点协变,
在定义泛型类VideoDetail<out T>时,当我们在泛型类型T前面添加out,VideoDetail为T的协变类。在该类的作用域内,类型T只能作为该类中函数的返回类型,不能作为参数传递进来,这时也称做VideoDetail为T的生产者(Producer)。
以此类推,在定义泛型类AlbumDetail<in T>时,当我们在泛型类型T前面添加in,AlbumDetail为T的逆变类。在该类的作用域内,类型T只能作为该类中函数的参数传递进来,不能作为返回类型,这时也称做AlbumDetail为T的消费者(Consumer)。

fun main(args: Array<String>) {

    var video: VideoDetail<Any> = VideoDetail<String>()
    video.modifyData(123)
    println((video.data as String).length)


    var album: AlbumDetail<String> = AlbumDetail<Any>()
    println(album.data?.length)

}

class VideoDetail<out T> (var data: @UnsafeVariance T? = null) {

    fun modifyData(data: @UnsafeVariance T?) {
        println(data is String)
        this.data = data
    }
}
class AlbumDetail<in T> (var data: @UnsafeVariance T? = null) 
泛型边界

java

public class VideoDetail<T extends Object> {
        private T data;
    }

kotlin

class AlbumDetail<T: Any> (var data: T? = null)

空安全

    var str: String? = null

    var len: Int? = str?.length

    println("len : " + len)

    var len2 = str!!.length//如果str为null 则抛出KotlinNullPointerException

    //类型转换安全 如果a 不是Int类型 则返回ull
    val aInt: Int? = a as? Int

相等判断

a === b 只有当a和b指向同一个对象才返回true。
a == b 会使用equals进行比较,一般翻译为:a?.equals(b) ?: (b === null)

lambda与函数类型

fun main(args: Array<String>) {

    var f: (Int, Int) -> String//定义一个函数类型的变量

    //lambda
    f = { a: Int, b: Int ->

        (a + b).toString()
    }

    println(f(1, 2))//打印 3

    f = fun(a: Int, b: Int): String {
        return (a * b).toString()
    }

    println(f(2, 8))//打印 16

    f = ::function

    println(f(3, 1))//打印 2


}

fun function(a: Int, b: Int): String {
    return (a - b).toString()
}

委托

委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。
Kotlin 直接支持委托模式,更加优雅,简洁。Kotlin 通过关键字 by 实现委托。


interface Base {
    fun print(msg: String)
}

class Delegate: Base {
    override fun print(msg: String) {
        println("Delegate: " + msg)
    }
}

class Person(delegate: Base): Base by delegate


//test
    var p = Person(Delegate())
    p.print("test") 
    //打印结果: Delegate: test

属性委托

class Example {
    var p: String by Delegate()
}

// 委托的类
class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, 这里委托了 ${property.name} 属性"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef 的 ${property.name} 属性赋值为 $value")
    }
}
fun main(args: Array<String>) {
    val e = Example()
    println(e.p)     // 访问该属性,调用 getValue() 函数

    e.p = "Runoob"   // 调用 setValue() 函数
    println(e.p)
}

延迟属性 Lazy

lazy() 是一个函数, 接受一个 Lambda 表达式作为参数, 返回一个 Lazy <T> 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lamda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。

fun main(args: Array<String>) {
    var demo = Demo()
    println(demo.str)
    println(demo.str)
}

class Demo {
    val str: String by lazy{
        println("init")
        "Hello"
    }
}
//打印结果
/**
init
Hello
Hello
*/

可观察属性 Observable

observable 可以用于实现观察者模式。
Delegates.observable() 函数接受两个参数: 第一个是初始化值, 第二个是属性值变化事件的响应器(handler)。
在属性赋值后会执行事件的响应器(handler),它有三个参数:被赋值的属性、旧值和新值:

fun main(args: Array<String>) {
    var demo = Demo()
    demo.name = "zhangsan"
    demo.name = "lisi"
}

class Demo {

    var name: String by Delegates.observable("init value"){
        prop, old, new ->
        println("旧值:$old  新值: $new")
    }
}
//打印结果
/**
旧值:init value  新值: zhangsan
旧值:zhangsan  新值: lisi
*/

集合

fun main(args: Array<String>) {
    //可变集合
    var mutableList: MutableList<String> = mutableListOf("1", "2", "3")
    mutableList.add("4")
    println(mutableList)

    var mutableSet: MutableSet<String> = mutableSetOf("1", "2", "3")
    mutableSet.add("4")
    println(mutableSet)

    var mutableMap: MutableMap<String, String> = mutableMapOf("a" to "1", "b" to "2", "c" to "3")
    mutableMap.put("d", "4")
    println(mutableMap)



    //不可变集合
    var list: List<String> = listOf("1", "2", "3")
    //list.add("4") //编译报错 没有这个方法
    println(list)

    //遍历
    list.forEach { println(it) }

    var map:Map<String, String> = mapOf("a" to "1", "b" to "2", "c" to "3")
    //map.put("d", "4")//编译报错 没有这个方法
    println(map)




    var arrayList = ArrayList<String>()
    arrayList.add("1")
    arrayList.add("2")
    arrayList.add("3")
    println(arrayList)

    var map2 = HashMap<String, String>()
    map2.put("a", "1")
    println(map2)

    var set2 = TreeSet<String>()
    set2.add("1")
    set2.add("2")
    set2.add("3")
    println(set2)
}

扩展

Kotlin和c#、Gosu一样,能够扩展一个类的新功能,而无需继承类或使用任何类型的设计模式,如装饰者。


fun MutableList<String>.swap(index1: Int, index2: Int) {
    val tmp = this[index1]
    this[index1] = this[index2]
    this[index2] = tmp
}

fun main(args: Array<String>) {
    var mutableList: MutableList<String> = mutableListOf("1", "2", "3")
    mutableList.add("4")
    println(mutableList)

    mutableList.swap(0, 1)
    println(mutableList)

}

扩展的静态解析

扩展不能真正的修改他们继承的类。通过定义一个扩展,你不能在类内插入新成员, 仅仅是通过该类的实例用点表达式去调用这个新函数。

fun main(args: Array<String>) {

    var stu = Student()
    log(stu)

    var person = BasePerson()
    println(person.log())

}
open class BasePerson {
    var name: String? = null
    var age: Int? = null
    fun log() = "log"
}
class Student: BasePerson() {
    var number: Int? = null
}

fun BasePerson.get() = "BasePerson"

fun Student.get() = "student"

fun BasePerson.log() = this.toString()

fun log(obj: BasePerson) {
    println(obj.get())
}

Android开发

class MainActivity : AppCompatActivity() {

    companion object {
//        const val TAG: String? = MainActivity::class.simpleName
        const val TAG = "MainActivity"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //id 是 textView
        textView.text = "hello"

        //如果lamda 参数只有一个可以省略
        textView.setOnClickListener {

            Log.i(TAG, "it : " + it)

        }

        val textview1 = find<TextView>(R.id.textView)
        textview1.text = "hello2"

        toast("toast")

        longToast("longToast")


        //子线程任务
        async {
            Log.i(TAG, "thread name:" + Thread.currentThread().name)

            //主线程
            uiThread {
                Log.i(TAG, "thread name:" + Thread.currentThread().name)
            }
        }


    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值