Kotlin学习-基础篇(一)

2018-12-27  本文已影响7人  CoderChao

Kotlin简介

Kotlin应用不同领域

Kotlin开发环境

Kotlin的优点

定义变量

val a: Int = 1  // 显式标明类型,立即赋值  
val b = 2   // 自动推断出 `Int` 类型  
var c: Int  // 如果没有初始值类型不能省略  
c = 3       // 明确赋值

var和val的区别

var name = "我是可改变的"  
println(name)  
name = "我真的是可改变"  
println(name)  
val finalValue = "我是不可改变的";  
println(finalValue); 

类定义

//类定义,继承类和实现接口
class FeedBackActivity : NativeBaseActivity(), View.OnLongClickListener, BitmapUtil.SaveImageCall {
    
}
val invoice = Invoice()
val customer = Customer("Joe Smith")
//注意 Kotlin 并没有 new 关键字。

函数定义

Kotlin 中的函数使用 fun 关键字声明,参数即 name: type。参数用逗号隔开

fun double(x: Int): Int {
    return 2 * x
}
fun sum(a: Int, b: Int): Int {
    return a + b
}

也可以

fun sum(a: Int, b: Int) = a + b
//支持默认参数值,减少方法重载
fun showToast(message: String, duration:Int = Toast.LENGTH_LONG) {
    Toast.makeText(this, message, duration).show()
}

//调用方式:没有默认值的参数,调用时,必须填写
showToast("toast");
showToast("toast", Toast.LENGTH_LONG);
//Java
public static void main(String[] args){

}
//Kotlin
fun main(args:Array<String>){
   
}

主次构造函数

在Kotlin中的一个类可以有一个主构造函数和一个或多个次构造函数

  1. 主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块
  2. 主构造函数中声明的属性可以是可变的(var)或只读的(val)
//如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的,并且这些修饰符在constructor前面:
class Customer public @Inject constructor(name: String) { …… }

//无修饰可不写constructor关键字
class Customer (name: String) {
    var a :Int = 1
    init{……}
}
//如果类有一个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托。委托到同一个类的另一个构造函数用 this 关键字即可:
class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}
  1. 如果没有构造函数,将会默认一个无参数构造函数
  2. 如果主构造函数的所有的参数都有默认值,编译器会生成一个额外的无参构造函数,它将使用默认值。
//如构造函数为私有,需用private修饰
class DontCreateMe public constructor () {

}

class Customer(val customerName: String = ""){}

函数调用

val result = double(2)
Sample().foo() // 创建类 Sample 实例并调用 foo

字符串模板

val book = Book("Thinking In Java", 59.0f, "Unknown")
val extraValue = "extra"
Log.d("MainActivity", "book.name = ${book.name}; book.price=${book.price};extraValue=$extraValue")

区间

区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。

if (i in 1..10) { // 等同于 1 <= i && i <= 10
    println(i)
}

//顺序
for (i in 1..4) print(i) // 输出“1234”
for (i in 4..1) print(i) // 什么都不输出

//倒序
for (i in 4 downTo 1) print(i) // 输出“4321”

//要创建一个不包括其结束元素的区间,可以使用 until 函数:
for (i in 1 until 10) {   // i in [1, 10) 排除了 10
     println(i)
}

//能否以不等于 1 的任意步长迭代数字? 当然没问题, step() 函数有助于此:每循环到第二个元素就剔除

for (i in 1..4 step 2) print(i) // 输出“13”

for (i in 4 downTo 1 step 2) print(i) // 输出“42”


控制流:if、when、for、while

if表达式

if和Java用法一致

val max = if (a > b) a else b
when表达式

when它能完全取代switch/case,也可以用来取代 if-else if链,并且还有很多新的特性。

如果其他分支都不满足条件将会求值else分支。 如果 when 作为一个表达式使用,则必须有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了。

//分支条件可以是:Int,区间,方法,字符串,对象等
when (x) {
    0, 1 -> print("x == 0 or x == 1")
    in 2 -> print("x == 2")
    in 3..8 -> print("x == 3..8")
    parseInt(s)-> print("parseInt")
    is String -> print("x is String")
    else -> print("otherwise")
}


fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")//智能转换
    else -> false
}

//when 也可以用来取代 if-else if链。 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支:
when {
    x.isOdd() -> print("x is odd")
    x.isEven() -> print("x is even")
    else -> print("x is funny")
}

for 循环
for (item in collection) print(item)

//循环体可以是一个代码块。
for (item: Int in ints) {
    // ……
}


for (i in 1..3) {
    println(i)//输出“123”
}

for (i in 6 downTo 0 step 2) {
    println(i)//输出“6420”
}

//如果想索引遍历,可以通过indices函数
for (i in array.indices) {
    println(array[i])
}

//或者你可以用库函数 withIndex:
for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}
//输出:
the element at 0 is a
the element at 1 is b
the element at 2 is c

While 循环

while 和 do..while 照常使用,省略

Kotlin 有三种结构化跳转表达式:

特殊符号?和!!

private var cloth_Rv: RecyclerView ?= null
cloth_Rv!!.setHasFixedSize(true)

可见性修饰符

类、对象、接口、构造函数、方法、属性和它们的 setter 都可以有 可见性修饰符。 在 Kotlin 中有这四个可见性修饰符:private、 protected、 internal 和 public。 如果没有显式指定修饰符的话,默认可见性是 public

重要关键字

Any

在Kotlin中所有类都有一个共同的超类Any,Any并不是Object

open

  1. 修饰类:表示能被继承
  2. 修饰方法:表示需要重写

final、open、abstract、override对比

修饰符 相应类的成员 注解
final 不能被重写 在kotlin中默认所有的方法和类都是final属性
open 可以被重写 需要被明确指出
abstract 必须要重写 不能被实例化,默认具有open属性
override 覆写超类的方法 如果没有被指定为final,则默认具有open属性

companion 伴生对象

//可以省略Factory
class MyClass {
     companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()

内部类和匿名内部类

//如果需要调用成员变量,需要用inner修饰内部类
class Outer {
    private val bar: Int = 1
    inner class Inner {
        fun foo() = bar
    }
}

val demo = Outer().Inner().foo() // == 1
//匿名内部类
textView.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
       //...
    }
})

扩展

函数扩展可以让你对任意类进行扩展,而不用继承等等复杂的操作。

对参数的解释:

扩展函数

fun Context.showToast(content: String, duration: Int = Toast.LENGTH_SHORT): Toast {
    val toast = Toast.makeText(MyApplication.context, content, duration)
    toast.show()
    return toast
}

这样只要是Context的子类,任何地方都可以调用Toast了

扩展属性

var View.padLeft: Int
    set(value) {
        setPadding(value, paddingTop, paddingRight, paddingBottom)
    }
    get() {
        return paddingLeft
    }
    //调用 textView.padLeft = 16

Any扩展函数

apply

val task = Runnable { println("Running") }
val thread = Thread(task)
thread.setDaemon(true)
thread.start()

以上代码可以简化为:

val task = Runnable { println("Running") }
Thread(task).apply { setDaemon(true) }.start()

如有问题欢迎留言,感谢支持和关注。

上一篇下一篇

猜你喜欢

热点阅读