Kotlin学习笔记(二)--和java重点区别的地方

kotlin笔记第二篇

一.构造器Constructor

1.声明的变量,如果有构造器的话,可以不用第一时间初始化

class User {

    val name: String
    val id: Int

    //默认public
    constructor(name: String, id: Int) {
        this.name = name
        this.id = id
    }
}

2.初始化代码块用init

class User {

    //初始化代码块,优先于构造器执行
    init {

    }

    val name: String
    val id: Int

    //默认public,在初始化代码块init之后执行
    constructor(name: String, id: Int) {
        this.name = name
        this.id = id
    }
}

3.final的使用
javafinalkotlin中的val类似,区别在于Kotlin 函数参数默认是 val 类型,且val变量的get函数可改动

fun method(message: String) {
    message = "asdf" //会报错
}

4.val修饰的变量不能再次赋值,但是可以修改get方法,

val id: Int
	//每次获取id值,都会x10
    get() {
        return field * 10
    }

5.staticobject关键字
java里通常定义静态常量如下

public static final int MAX_SIZE = 100;

kotlin里定义静态常量如下,使用object注意:是小写,不同于javaObjectjavaObjectkotlin里是Any

class User {

	//使用 companion object
    companion object {
        const val MAX_SIZE: Int = 100
    }

}

object 修饰的对象中的变量函数都是静态的,用object修饰的类就是单例,简单说就是

object 其实是把两步合并成了一步,既有 class 关键字的功能,又实现了单例

单例类(饿汉式的单例,并且实现了线程安全)

object A {
    val number: Int = 1
    fun method() {
        println("A.method()")
    }
} 

object还可以创建匿名类

6.companion关键字

companion 可以理解为伴随、伴生,表示修饰的对象和外部类绑定

一个类里,部分属性是静态的,部分不是,如下:

class A {

    //没有object修饰的不是静态的
    val age = 10

    //有companion的是伴生对象,一个类只能有一个伴对象,B可以省略
    //可以直接A.MAX_SIZE
    companion object B {
        val MAX_SIZE: Int = 100
    }

    //其他object修饰的是嵌套对象,可以有多个
    //引用只能A.C.MIN_SIZE
    object C {
        val MIN_SIZE: Int = 50
    }
}

二.top-level property / function 顶层声明

1.将属性或者函数的声明放在class之外,如下

package com.kotlinpractice.kotlin

val GLOBAL_AGE: Int = 10

fun globalGetScreenHeight(): Int {
    return 0
}

class Util {
    //类内部
}

引用的时候可以直接全局引用:

open class KotlinTestActivity : AppCompatActivity(), Impl {

    final override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //可以直接引用
        GLOBAL_AGE
        globalGetScreenHeight()
    }

}

这样的属性和函数不属于任何class,直接属于package

不同包下的顶级函数,名字可以相同,使用的时候会自动导入不同的包名区分

顶层声明的一般用于工具类等

三.常量

java定义常量

public static final int MAX_SIZE = 100;

kotlin定义常量

class A {

    //伴生对象的常量 加上 const
    companion object B {
        const val MAX_SIZE: Int = 100
    }

    //嵌套对象的常量 加上 const
    object C {
        const val MIN_SIZE: Int = 50
    }
}
Kotlin 的常量必须声明在对象(包括伴生对象)或者「top-level 顶层」中,因为常量是静态的。
Kotlin 中只有基本类型和 String 类型可以声明成常量。

四.数组

上一节的基本数据类型介绍中有IntArray,使用intArrayOf()函数如下

//类型都可以省略,kotlin自动推断
var number: Int = 10//还有Double Float Long Short Byte
var char: Char = 'c'
var isFood: Boolean = true
var ages: IntArray = intArrayOf(1, 2, 3)//FloatArray DoubleArray CharArray
var str: String = "Lili"

声明一个数组,

//类型都可以省略,kotlin自动推断
var number: Int = 10//还有Double Float Long Short Byte
var char: Char = 'c'
var isFood: Boolean = true
var ages: IntArray = intArrayOf(1, 2, 3)//FloatArray DoubleArray CharArray
var str: String = "Lili"
//声明数组,对象类型,使用arrayOf()函数
var strs: Array<String> = arrayOf("a", "b", "c")

调用同java,直接去下标

fun testArray() {
    strs[1] = "B"
}

五.集合

1.list,使用listOf函数

//类型都可以省略,kotlin自动推断
var number: Int = 10//还有Double Float Long Short Byte
var char: Char = 'c'
var isFood: Boolean = true
var ages: IntArray = intArrayOf(1, 2, 3)//FloatArray DoubleArray CharArray
var str: String = "Lili"
//声明数组,对象类型,使用arrayOf()函数
var strs: Array<String> = arrayOf("a", "b", "c")//不支持协变
//声明list,对象类型,使用listOf()函数
var strList: List<String> = listOf("a", "b", "c")//支持协变

协变就是子类对象赋值给父类对象

数组list对比,使用基本数据类型的时候,还是用数组更好一些,不用装箱

2.set,使用setOf函数

//类型都可以省略,kotlin自动推断
var number: Int = 10//还有Double Float Long Short Byte
var char: Char = 'c'
var isFood: Boolean = true
var ages: IntArray = intArrayOf(1, 2, 3)//FloatArray DoubleArray CharArray
var str: String = "Lili"
//声明数组,对象类型,使用arrayOf()函数
var strs: Array<String> = arrayOf("a", "b", "c")//不支持协变
//声明list,对象类型,使用listOf()函数
var strList: List<String> = listOf("a", "b", "c")//支持协变
//声明set,对象类型,使用setOf()函数
var strSet: Set<String> = setOf("a", "b", "c")//支持协变

3.map,使用mapOf函数

//类型都可以省略,kotlin自动推断
var number: Int = 10//还有Double Float Long Short Byte
var char: Char = 'c'
var isFood: Boolean = true
var ages: IntArray = intArrayOf(1, 2, 3)//FloatArray DoubleArray CharArray
var str: String = "Lili"
//声明数组,对象类型,使用arrayOf()函数
var strs: Array<String> = arrayOf("a", "b", "c")//不支持协变
//声明list,对象类型,使用listOf()函数
var strList: List<String> = listOf("a", "b", "c")//支持协变
//声明set,对象类型,使用setOf()函数
var strSet: Set<String> = setOf("a", "b", "c")//支持协变
//声明map
var map: Map<Int, String> = mapOf(1 to "a", 2 to "b", 3 to "c")

调用,取值

fun testArray() {
    strs[1] = "B"
    //map取值,都可以,编辑器推荐用第二种
    val value1 = map.get(1)
    val value2 = map[2]
}

赋值,则不能使用mapOf创建的map集合,需要使用mutableMapOf创建的集合,
添加代码:

var mapChange: MutableMap<Int, String> = mutableMapOf(1 to "a", 2 to "b", 3 to "c")

即可更改map

fun testArray() {
    strs[1] = "B"
    //map取值
    val value1 = map.get(1)
    val value2 = map[2]
    //可改值的map赋值
    mapChange.put(1, "A")
    mapChange[1] = "A"
}

同理,listOfsetOfmapOf,创建的都是不可变的集合,需要对应的mutableListOfmutableSetOfmutableMapOf才可创建可以改变值的集合

也可以用listOf创建的集合后调用toMutableList注意返回的是新的可变的集合,旧的集合仍旧是不可变的

fun testArray() {
    strs[1] = "B"
    //map取值
    val value1 = map.get(1)
    val value2 = map[2]
    //可改值的map赋值
    mapChange.put(1, "A")
    mapChange[1] = "A"
    //不可变list改为可变list,注意返回的是可变的,但strList还是不可变的
    val staListChange = strList.toMutableList()
}

六.Sequence——kotlin特有的类型

SequenceIterable一样,用来遍历一组数据并可以对每个元素进行特定的处理

三种创建方式:

//sequence
var sequence: Sequence<String> = sequenceOf("a", "b", "c")//用一组元素创建
var sequence2: Sequence<String> = strList.asSequence()//使用已创建的list列表转换
var sequence3: Sequence<Int> = generateSequence(0) { it + 1 }//使用lambda表达式创建,0是第一个元素,it表示前一个元素

七.可见性修饰符

kotlin有四种修饰符publicprivateprotectedinternal

1.publicjava中要显示声明,kotlin里默认都是public

2.internal:暂时不是很明白,原文记录下

internal 表示修饰的类、函数仅对 module 内可见,这里的 module 具体指的是一组共同编译的 kotlin 文件,常见的形式有:
1.Android Studio 里的 module
2.Maven project
我们常见的是 Android Studio 中的 module 这种情况,Maven project 仅作了解就好,不用细究。

internal 在写一个 library module 时非常有用,当需要创建一个函数仅开放给 module 内部使用,不想对 library 的使用者可见,这时就应该用 internal 可见性修饰符。

3.protectedjava中表示包内可见 + 子类可见,kotlin表示private + 子类可见

4.privatejava中表示类中可见,作为内部类时对外部类「可见」,即外部类可以访问内部类的 private 变量,而kotlin中表示类中或所在文件内可见,作为内部类时对外部类「不可见」

class B {

    private val age = 10 //整个文件可见

    class C {
        private val name = "jack" //仅 C 类中可见
        fun testC() {
            val b: B = B()
            b.age//内部类可以访问外部的private属性
        }
    }

    fun testB() {
        val c: C = C()
        c.name //报错,提示name属性是private,外部类无法访问内部类变量
    }
}

javaprivate不能用来修饰classinterface,因为修饰后就无法被使用,而kotlin中可以用private修饰classinterface,因为kotlin存在顶层声明,所以可以使用,比如之前的工具类,可以修改为

package com.kotlinpractice.kotlin

val GLOBAL_AGE: Int = 10

fun globalGetScreenHeight(): Int {
    return 0
}

private class Util {
    //类内部,使用private修饰
}

你可能感兴趣的:(Kotlin)