Kotlin基础

2021-01-18  本文已影响0人  不睡太晚不说太满
忙碌了一年,期间也学习了不少东西,但是没时间整理,乘着快过年了不是很忙的时候把学习的 Kotlin 知识记录一下。使用的好处就不用说了。

和 Java 一样,Kotlin 的数据类型也基本一个意思,只不过在 Kotlin 里是真的万物皆对象。

Boolean类型 Boolean
Number整型 Short Int Long
Number浮点型 Float Double
Number字节 Byte
字符型 Char
字符串型 String
Arrays 数组型 intArrary StringArrary 等

在申明变量时的使用方式上和 Java 也是有一点的区别。

val aBoolean : Boolean = true
val age: Int= 26
val name: String= "Leon"
val args: IntArrary= "intArraryOf(1,2,3,4,5)"

Kotlin中是不允许隐式转换, 每个 Number 类型的变量支持如下方法进行转换:

toByte() : Byte
toShort() : Short
toLong() : Long
toFloat() : Float
toDouble() : Double
toChar() : Char
如:val a : Int = b.toInt()

val : 申明为常量,类似于Java中的 final 只能赋值一次,后续不可更改
var : 申明变量,就是不加 final 的变量,允许重新赋值

val age: Int= 26 赋值为26后 后续行为中不允许再更改
var aBoolean : Boolean = true 后续行为中允许把值更改为 false
val a = 1 如果没有申明类型,Kotlin 会自动 类型推导 为"Int"类型
运行时常量:val x = getX()
编译器常量:const val x = getX()

字符串模板$,如果需要打印字符串加别的类型的日志时可以通过以下方式:

val year : Int = 2021
System.out.println("今年是 $year 年")
打印出: 今年是2021年

字符串比较 =====

a == b 表示比较内容, 即类似 Java 的 a.equals(b)
a === b 表示比较对象是否相同

创建一个类和对象

// 方式一:如果只有一个构造方法时  constructor 可以省略
class Star constructor(var name : String, var age : Int, var sex : Int) {
    // 初始化代码块
    init{
        println("new了一个明星  名字$year 年龄$age 性别$sex")
    }
}
// 创建一个22岁名字叫Leon的男明星对象

val star: Star= Star( "Leon",22,1)

类的继承
首先把 Star 类加了一个 Open 前缀

open class Star (var name : String, var age : Int, var sex : Int)
// 继承 Star 类
class ChildStar(var name : String, var age : Int, var sex : Int) : Star (name ,age,sex) {
  init{
        println("new了一个童星  名字$year 年龄$age 性别$sex")
    }
}
// 创建一个8岁名字叫Alisa的女童星对象
val star: Star= Star( "Alisa",8, 2)

class <类名> { <成员> }
提取多个类的共性得到一个更抽象的类,即父类。子类拥有父类的一切特征。子类也可以自定义自己的特征。所有类都最终继承自 * Any *

空类型

在java中我们通常在Util类中处理部分逻辑最后得到结果,一般情况下得到的是两种结果, 1. 返回的所需数据 2.返回的 null。如下:

// Java
public static String getName(){
  if(...) {
    return "Leon";
  }
  return null;
}

String name = Util.getName()
if(name != null){
  println(name.length()) 
}

但是这种写法在Kotlin中却不行, 因为Kotlin会认为你这的方法返回的值并不安全,可能会导致空异常。所以在Kolint中的写法是:

open fun getName() :String? {
    if(...) {
    return "Leon";
  }
  return null;
}
val name : String? = Util.getName()
println(name?.length()) 

在函数中如果返回值为null会强制在返回类型中加上?.使用时也同样需要在变量名后面加上?, 代表是可空类型。

在平时使用中, 我们会申明不少变量, 为遇到如下几种情况:

val value1 : String = "你好"
var value2 : String? = null

一种是确定变量的值, 一种是不确定, 需要默认是null的。如果是第二种, 则声明时类型后面必须要加上?,否则编译器爆红, 并且不可使用 val修饰。

如果返回类型是可空的, 但是又不想使用?时 可以使用!!来告诉编译器,你可以确定这个值不会为空。(这种方式需要慎重)

var value : String = null // 申明了一个可空的变量
override fun onCreate(savedInstanceState:Bundle?){
  value = "你好" // 在使用时就可以肯定是有赋值的
  Log.e(TAG, value?.length)  // 但是在使用时还是必须加上`?`, 怎么办呢?
  Log.e(TAG, value!!.length)  // 可以使用双`!!`告诉编译器 '我可以确定他不会为空'
}

任意类型都有可空和不可控两种

val notNull: String = null // 错误,不能为空
val nullable: String? = null // 正确, 可以为空

val notNull.length // 正确,不为空的值可以直接使用
val nullable.length // 错误,可能为空,不能直接获取长度
val nullable!!.length //正确,强制 认定nullable不可空
val nullable?.length //正确,强制 若nullable为空,就返回空

智能类型转换
public staticc void main(String... args){
    Star childstar = new Star();
    // 方式1
    (Star)chilstar.getName()
    //方式2
    if(childstar instanceof Star){
       println((Star)chilstar.getName())
    }
}

以上代码中足以体现出Java中不智能的表现, 明明ChildStar就是继承与Star, 但是在使用时还需要强转一次,方式2中也明明做了 instanceof 判断,在使用时还是需要强转一次。下面使用Kotlin来体现:

fun main(args :Array<String>){
    val childstar = Star()
    if(childstar is Star){
        println(childstar.getName())
    }
}

在Kotlin中我们通过了 is关键字判断了是否是 Star 类型, 如果是编译器就自动推到出了 childstar 是 Star 的子类,已经不需要再次强转了。

Java Style 类型转换
val sub: SubClass = parent as SubClass // 类型与Java的类型转换,失败则抛出异常
Kotlin安全类型转换
val sub: SubClass = parent as? SubClass // 如果转换失败,返回null,不抛异常
Kotlin智能类型转换
if(parent is SubClass) parent.<子类的成员> // 编译器尽可能的推导类型,远离无用的类型转换

区间是一个数学上的概念,表示范围,CloseRange的子类。比如[0, 1024] 的这个整型区间的表达为

val range1 :IntRange = 0..1024

除了这种方式外还有一个关键字 until 也可以表达区间:

val range2 : IntRange = 0 until 1024

但是这种方式是和第一种是有区别的,我们通过for循环来看一下:

for(i in range1 ){
  println(i) // 最后输出的是1024
}

for(j in range2){
  println(j) // 最后输出的是1023
}

由此可见 0 until 1024 是一个 半开区间 [0, 2014)

除了 Array 外 Kotlin 还给我们提供了 IntArry, ShortArray, ByteArray, CharArry 等。

val arrayOfInt : IntArray = intArrayOf(1,3,5,4,5)
val arrayOfChar : CharArray = charArrayOf('h','e','l','l','o')
val arrayOfString = Array<String> = arrayOf("你","好")
val arrayOfStar = Array<Star> = arrayOf(childStar1,childStar2)

// 数组的遍历
for (i in arrayOfInt) {
    parintlin(i)
}

// 打印童星中的第二个
parintlin(childStar2[1].getName())

// 改变数组的第一个元素
arrayOfInt [0] = 10

// 切片
parintlin(arrayOfInt.sliec(1..2)) // 打印[3,5]
上一篇下一篇

猜你喜欢

热点阅读