Kotlin入门

Kotlin 基础:

函数声明:

  • 声明函数要⽤ fun 关键字
  • 「函数参数」的「参数类型」是在「参数名」的右边
  • 函数的「返回值」在「函数参数」右边使⽤ : 分隔,没有返回值时可以省略

声明没有返回值的函数:

fun main() {
 //..
}

声明有返回值的参数:

fun sum(x: Int, y: Int): Int {
 return x + y 
}

 变量声明:

  • 声明变量需要通过关键字: var 声明可读可写变量; val 声明只读变量
  • 「类型」在「变量量名」的右边,⽤ : 分割,同时如果满⾜「类型推断」,类型可以省略
  • 创建对象直接调⽤构造器,不需要 new 关键字

声明可读可写变量: 

var age: Int = 18

声明只读变量:

val name: String = "Hello, Kotlin!"

声明对象: 

val user: User = User()

类型推断:

在变量声明的基础上,如果表达式右边的类型是可以推断出来,那么类型可以省略 :
 
var age = 18
val name = "Hello, Kotlin!"
val user = User()

继承类/实现接⼝:

继承类和实现接⼝都是⽤的 : 继承的类在后面要追加()括号,实现的接口不需要追加()括号

class MainActivity : BaseActivity(), View.OnClickListener

空安全设计:

Kotlin 中的类型分为「可空类型」和「不可空类型」:

  • 不可空类型
val editText : EditText
  • 可空类型
val editText : EditText?

调⽤符:

  • !! 强⾏调⽤符
  • ?. 安全调⽤符

lateinit 关键字:

  • lateinit 只能修饰 var 可读可写变量(因为它只是延迟初始化)
  • lateinit 关键字声明的变量的类型必须是「不可空类型」
  • lateinit 声明的变量不能有「初始值」
  • lateinit 声明的变量不能是「基本数据类型」
  • 在构造器中初始化的属性不需要 lateinit 关键字

平台类型:

IDE编译器在类型后⾯有⼀个感叹号代表是「平台类型」,这个感叹号是编译器提示的,而不是代码打出来的;意思是其它平台生成\返回的类型,它不知道是否为空,平台类型在调用过程中,可以不使用安全调用符调用,但是如果在调用的过程中返回的是Null值,那么还是会抛出空指针异常;
 
Java 中可以通过注解减少这种平台类型的产⽣
  • @Nullable 表示可空类型
  • @NotNull @NonNul l 表示不可空类型

类型判断:

  • is 判断属于某类型
  • !is 判断不属于某类型
  • as 类型强转,失败时抛出类型强转失败异常
  • as? 类型强转,但失败时不会抛出异常⽽是返回 null

获取 Class 对象:

  • 使⽤ 类名::class 获取的是 Kotlin 的类型是 KClass
  • 使⽤ 类名::class.java 获取的是 Java 的类型

setter/getter:

Kotlin 声明属性的时候 ( 没有使⽤ private 修饰 ) ,会⾃动⽣成⼀个私有属性和⼀对公开的 setter/getter 函数。 在写 setter/getter 的时候使⽤ field 来代替内部的私有属性 ( 防⽌递归栈溢出 )
 
显式的声明一个set和get函数:
    var code: String? = null
        set(value) {
            field = value
        }
        get() {
            return field;
        }
为什么 EditText.getText() 的时候可以简化,但是 EditText.setText() 的时候不能和 TextView.setText() ⼀样简化 ? 因为 EditText.getText() 获得的类型是 Editable ,对应 的如果 EditText.setText() 传⼊的参数也是 Editable 就可以简化了。
 
val newEditable = Editable.Factory.getInstance().newEditable("Kotlin")
et_username.text = newEditable

 不写set、get函数时,kotlin会默认生成一个公共的set、get函数,如果想要修改某一个set\get的可见性,需要在变量的下面声明可见性 [修饰符] set\get

下面这个示例代码,set函数为private,get函数默认为publick
    var code: String? = null
        private set

 

构造器:

使⽤ constructor 关键字声明构造器

class User {
 constructor()
}
如果我们在构造器主动调⽤了⽗类构造,那么在继承类的时候就不能在类的后⾯加上⼩括号
 
//在单参数的构造函数里,主动调用了双参数的构造函数
constructor(context: Context) : this(context, null)
// 双参数构造函数主动调⽤⽤了⽗类的构造器
constructor(context: Context, attr: AttributeSet?) : super(context, attr)

构造器的完整写法:

class CodeView : TextView {
 constructor(context: Context): super(context) 
}

构造器的简化写法:

class CodeView  constructor(codeView: Context) : TextView(codeView) {
   /.../
}
如果没有被「可⻅性修饰符」「注解」标注,那么 `constructor` 可以省略
class CodeView(codeView: Context) : TextView(codeView) {
   /.../
}

 

构造器的简化写法不能包含任何初始化代码,初始化代码可以放到 init 代码块中

class CodeView(var codeView: Context) : TextView(codeView) {
    init {
        /.../
    }
}

在初始化的时候,初始化块会按照它们在「⽂件中出现的顺序」执⾏。

class CodeView(var codeView: Context) : TextView(codeView) {
    init {
        /.../
    }
    val paint = Paint() // 会在 init{} 之后运⾏
}

 

构造器的简化写法参数前⾯加上 var/val 使构造参数同时成为成员变量

构造函数的变量不加变量修饰符,默认只能成员变量赋值时访问
class CodeView(codeView: Context) : TextView(codeView) {
    val color = codeView.getColor(R.color.colorWhite)
}

加了变量修饰符后,使其成为成员变量
class CodeView(var codeView: Context) : TextView(codeView) {
    val color = codeView.getColor(R.color.colorWhite)

    fun test() {
        codeView.getColor(R.color.colorWhite)
    }
}

@JvmField ⽣成属性:

通过 @JvmField 注解可以让编译器只⽣成⼀个 public 的成员属性,不⽣成对应的 setter/getter 函数;
    @JvmField
    var value: String = "1";

Any 和 Unit:

  • Any: Kotlin 的顶层⽗类是 Any ,对应 Java 当中的 Object ,但是⽐ Object 少了 wait()/notify() 等函数
  • Unit: Kotlin 中的 Unit 对应 Java 中的 void

数组:

使⽤ arrayof() 来创建数组,基本数据类型使⽤对应的 intArrayOf() 等;

    val codeList = arrayOf("1", "2", "3")
    val intList = intArrayOf(1, 2, 3)

静态函数和属性:

  • 顶层函数; 生成真正的静态函数,但是在同一个层级包下,不能生成同名的静态函数
  • object;      类名用object来修饰;代表生成单例对象,在kotlin中跟Java中调用静态函数的方式是一样的,但实际上是通过单例对象来调用函数;在Java中调用需要用类名.INSTANCE.方法名();
  • companion object;  类名如果是用class修饰的对象,可用该关键词在类里面生成伴生对象,生成后的对象为单例对象,在kotlin中跟Java中调用静态函数的方式是一样的,但实际上是通过单例对象来调用函数;在Java中调用需要用类名.Companion.方法名();
  • @JvmStatic; 通过这个注解将 object companion object 的内部函数和属性,真正⽣成为静态的。
其中,「顶层函数」直接在⽂件中定义函数和属性,会直接⽣成静态的,在 Java 中通过「⽂件名 Kt」来访问,同时可以通过在package上面声明@file:JvmName注解来修改这个「类名」的调用名称(仅在Java里调用起作用)。
  • 需要注意,这种顶层函数不要声明在 module 内最顶层的包中,⾄少要在⼀个包中例如 com 。不然不能⽅便使⽤。
object companion object 都是⽣成单例对象,然后通过单例对象访问函数和属性的。
 
顶层函数的声明:
 
package com.example.myapplication.kt
fun test() {
    
}

顶层函数的调用:

文件名为:
TestKt.kt
kotlin中调用:
   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        test()
    }
Java中调用:
TestKtKt.test();

object函数声明:

object TestKt {
    fun test1() {

    }
}

object函数调用:

文件名为:TestKt.kt
Kotlin调用:
TestKt.test1()
Java中调用:
TestKt.INSTANCE.test1();

companion object函数声明:

class TestKt {
    companion object{
        fun test1() {

        }
    }
}

companion object函数调用:

文件名为:TestKt.kt
Kotlin调用:
TestKt.test1()
Java中调用:
TestKt.Companion.test1();

@JvmStatic函数声明:

class TestKt {
    companion object{
        @JvmStatic
        fun test1() {

        }
    }
}

or

object TestKt {
    @JvmStatic
    fun test1() {

    }
}

 @JvmStatic函数调用:

文件名为:TestKt.kt
Kotlin调用:
TestKt.test1()
Java中调用:
TestKt.test1();

单例模式/匿名内部类 :

// 单例
object 类名 {
 
}
// 匿名内部类
object : OnClickListener {
 
}
 
声明一个内部类:
      findViewById<Button>(R.id.button_id).setOnClickListener(object : View.OnClickListener {
          override fun onClick(v: View?) {
              TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
          }
      } )
    }

字符串:

字符串模版:

val number = 100
val text = "向你转账${number}元。"
// 如果只是单⼀的变量,可以省略掉 {}
val text2 = "向你转账$number元。"

多⾏字符串:

val s = """
 我是第⼀⾏
 我是第⼆⾏
 我是第三⾏
 """.trimIndent()

区间:

200..299 表示 200 -> 299 的区间(包括 299 )

when 关键字:

Java 当中的 switch 的⾼级版,分⽀条件上可以⽀持表达式。

受检异常:

Kotlin 不需要使⽤ try-catch 强制捕获异常

声明接⼝/抽象类/枚举/注解:

// 声明抽象类
abstract class
// 声明接⼝
interface
// 声明注解
annotation class
// 声明枚举
enmu class
 
抽象属性
如果在 接口 中定义一个属性,就代表抽象属性,⼦类对抽象属性重写\继承的时候需要实现对应的
setter/getter
class TestKt :CodeView {
    override val test: String
        get() = "111"
}

interface CodeView {
    val test: String
}
 

静态常量:

静态常量,也叫做编译期常量,在静态变量(顶层函数\object\companion object\@JvmStatic)上加上 const 关键字变成编译期常量。

顶层声明静态常量:

package com.example.myapplication.kt
const val value = "1"

顶层函数调用静态常量:

文件名:TestKt.kt
Kotlin中调用:
val testValue = value
Java中调用:
String testValue = TestKtKt.value;

object声明静态常量:

object TestKt {
    const val value = "1"
}

object调用静态常量:

文件名:TestKt.kt
Kotlin中调用:
val testValue = TestKt.value
Java中调用:
String testValue = TestKt.value;

companion object声明静态常量:

class TestKt {
    companion object{
        const val value = "1"
    }
}

companion object调用静态常量:

文件名:TestKt.kt
Kotlin中调用:
val testValue = TestKt.value
Java中调用:
String testValue = TestKt.value;

companion object用@JvmStatic声明静态常量:

class TestKt {
    companion object {
        @JvmStatic val value = "1"
    }
}

 companion object用@JvmStatic调用常量:

文件名:TestKt.kt
Kotlin中调用:
val testValue = TestKt.value
Java中调用:
String testValue = TestKt.Companion.getValue();

object用@JvmStatic声明静态常量:

object TestKt {
    @JvmStatic
    val value = "1"
}

object用@JvmStatic调用常量:

文件名:TestKt.kt
Kotlin中调用:
val testValue = TestKt.value
Java中调用:
String testValue = TestKt.getValue();

获取⽬标类引⽤:

  • 在 Java 中通过「类名.this 例如 Outer.this 」 获取⽬标类引⽤
  • Kotlin 中通过「this@类名 例如 this@Outer 」获取⽬标类引⽤

遍历:

for(item in items)

通过标准函数 repeat()

循环100次
repeat(100) {
 //..
}
通过区间:
for (i in 0..99) {
}
// until 不包括右边界
for (i in 0 until 100) {
}

 

嵌套类:

Kotlin 当中,嵌套类默认是静态内部类 ( 不持有外部类引⽤ ) 在class\fun前加上 inner 关键字声明为普通内部类 ( 内部使⽤外部对象时就会持有外部类引⽤ )。
 

可⻅性修饰符:

默认的可⻅性修饰符是 public;新增的可⻅性修饰符 internal 表示仅在当前模块(Moudle)可⻅。
 

注释:

注释中可以在任意地⽅使⽤ [] 来引⽤⽬标,代替 Java 中的 @param @link 等。

⾮空断⾔:

可空类型强制类型转换成不可空类型可以通过在变量后⾯加上 !! ,来达到类型转换。

    var value: String? = null
    var value1 :String = value!!

open/final:

Kotlin中的类和函数,默认是被 final 修饰的 ( abstract override 例外)。除非在类型修饰符\函数修饰符前面加上 open 关键词,代表不用final修饰。

 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值