Kotlin

基本的定义

  • 静态语言
  • 修饰符
  • 函数
  • 返回类型(类型推倒 Int)
  • 函数的变长参数可以用 vararg 关键字
  • NULL检查机制
  • 类型监测以及自动类型转换
  • 区间
  • 比较
  • When表达式
  • For循环
  • 循环控制 @标签
  • 构造函数
  • 继承
  • 懒加载
    • 赋值
    • 设置允许为null
    • 懒加载,被调用必须有值
  • 接口
  • 抽象类
  • 继承
  • POJO实体类
  • 单例类(object)
  • Kotlin写单例
  • 内部类 (inner)

一个普通的Kotlin类定义

class ExampleUnitTest {
    
    val name = "Name";
    var age = "18";

    @Test
    fun main() {
        val info_1: String = "A";
        println(info_1)

        var info_2: String = "B";
        print(info_2)
    }

}

通过 Kotlin 编译成javac再看看 (Tools -- Kotlin -- show Kotlin Bytecode -- Decompile)

public final class ExampleUnitTest {
   @NotNull
   private final String name = "Name";
   @NotNull
   private String age = "18";

   @NotNull
   public final String getName() {
      return this.name;
   }

   @NotNull
   public final String getAge() {
      return this.age;
   }

   public final void setAge(@NotNull String var1) {
      Intrinsics.checkNotNullParameter(var1, "");
      this.age = var1;
   }

   @Test
   public final void main() {
      String info_1 = "A";
      boolean var2 = false;
      System.out.println(info_1);
      String info_2 = "B";
      boolean var3 = false;
      System.out.print(info_2);
   }
}
结论 关于 varval
  • var:可以修改,并且会在class中自动生成get/set函数
  • val:是不能修改,是用了 java中的 final修饰,所以只能 get

静态语言

kotlin是一门静态语言,在编译期就确定了类型,并且可以类型推倒

修饰符

访问权限修饰符
修饰符 类成员 作用域范围
public 所有地方可见 所有地方可见
internal 模块中可见 模块中可见
protected 子类中可见 父子类
private 类中可见 文件中可见
类修饰符
修饰符 说明
final 不能被继承
open 可以被继承
abstract 抽象类
enum 枚举类
data 数据类
sealed 密封类
annotation 注解类
inner 嵌套类(内部类)
seeled 密封类:
sealed class SealedExpr{
data class Person(val num1 : Int, val num2 : Int) : SealedExpr()

object Add : SealedExpr()   // 单例模式
object Minus : SealedExpr() // 单例模式
}

// 其子类可以定在密封类外部,但是必须在同一文件中 v1.1之前只能定义在密封类内部
object NotANumber : SealedExpr() 
  • 密封类是用来表示受限的 类继承结构,枚举enum升级版
  • 不能被实例化,可以有子类被继承
  • 在枚举中常量只能存在一个实例,而密封类可以存在多个实例
  • 有效的保护代码,使用when表达式从而验证语句不用添加else
成员修饰符
修饰符 说明
override 重写函数
open 可以被重写
final 不能被重写
abstract 抽象函数
lateinit 延迟初始化(var)
by lazy 延迟初始化(vrl)
  • lateinit 声明时候忽略初始化值,在后面用到的时候在初始化

    lateinit var test: String
    
  • by lazy 在头次被调用,才自动设置表达式初始化

    val str by lazy {
            println("Init lazy")
            "Hello World"
        }
    
泛型修饰
修饰符 说明
in 相当于Java中的super关键字的作用
out 相当于Java中的extends关键字的作用

函数

返回类型 Int
fun add(number1: Int, number2: Int): Int {
    return number1 + number2;
}

返回类型(类型推倒 Int)

fun add2(number1: Int, number2: Int) = number1 + number2

函数的变长参数可以用 vararg 关键字

fun lenMethod(vararg value: Int) {
    for (i in value) {
        print(i)
    }
}

NULL检查机制

//类型后面加? 表示可为空
var age: String? = "23" 

//抛出空指针异常
val ages = age!!.toInt()

//不做处理返回 null
val ages1 = age?.toInt()

//age为空返回-1
val ages2 = age?.toInt() ?: -1

kotlin在空安全设计对于声明可为空的参数,在使用要进行空判断处理,

  • 字段后面加 !!JAVA一样抛出异常
  • 另一种字段后加 可不做处理返回值为NULL

类型监测以及自动类型转换

可以用is运算检测一个表达式是否为某个类型,类型与instanceof关键字

  • Any 为 Object类型
fun getStringLength(obj: Any): Int? {
  if (obj !is String)
    return null
  // 在这个分支中, `obj` 的类型会被自动转换为 `String`
  return obj.length
}

区间

区间表达式由 ..in!in 组成

for (i in 1..4) print(i) // 输出“1234”

for (i in 4..1) print(i) // 什么都不输出 不支持递减区间

for (i in 4 downTo 1) print(i) //关键字 downTo 可以支持递减区间

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

// 使用 step 指定步长
for (i in 1..4 step 2) print(i) // 输出“13”

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


// 使用 until 函数排除结束元素
for (i in 1 until 10) {   // i in [1, 10) 排除了 10
     println(i)
}

比较

fun main(args: Array) {
    val a: Int = 10000
    println(a === a) // true,值相等,对象地址相等

    //经过了装箱,创建了两个不同的对象
    val boxedA: Int? = a
    val anotherBoxedA: Int? = a

    //虽然经过了装箱,但是值是相等的,都是10000
    println(boxedA === anotherBoxedA) //  false,值相等,对象地址不一样
    println(boxedA == anotherBoxedA) // true,值相等
}
  • 两个 == 表示比较两个值大小
  • 三个等号 === 比较对象地址

When表达式

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> { // 注意这个块
        print("x 不是 1 ,也不是 2")
    }
}

When in (!in) 区间
when (x) {
    in 1..10 -> print("x is in the range")
    in validNumbers -> print("x is valid")
    !in 10..20 -> print("x is outside the range")
    else -> print("none of the above")
}

For循环

方法一(区间)
var items = listOf("A", "B", "C", "D", "E", "F")

//方法一 
for (item in items){
    println(item)
}
方法二(闭包)
//方法二
items.forEach {
    println(it)
}
方法三(下标迭代)
//方法三
for (index in items.indices){
    println("下标: ${index} ,对应的值为: ${items[index]}")
}

循环控制 @标签

loop@ for (i in 1..20) {
    for (j in 1..20) {
        println("i:${i}   j:${j}")
        if (i == 5)
            break@loop

    }
}

可以通过 @xxx 自定义标签,break@xxx 退出循环

构造函数

构造函数由 主构造 & 次构造 constructor, 次构造必须调用主构造

class Person(id: Int) {  //主构造
    
    constructor() : this(id = 1) {  //次构造
    }

    constructor(id: Int, name: String) : this(id) { //次构造
    }

    constructor(id: Int, age: Int) : this(id) { //次构造
    }
}

通过编译文件查看

public final class Person {
   public Person(int id) {
   }

   public Person() {
      this(1);
   }

   public Person(int id, @NotNull String name) {
      Intrinsics.checkNotNullParameter(name, "name");
      this(id);
   }

   public Person(int id, int age) {
      this(id);
   }
}

继承

默认为 final 不能被继承, 所以父类需要被其他子类继承 加上关键字 open

open class Person(id: Int) {  //主构造

}

class Student : Person(10) {  //student 继承了 Person
}

懒加载

kotlin 变量一律没有默认值,

val name: String ; //报错, kotlin 变量一律没有默认值

有三种方式处理

赋值
val name: String = "Neng";
设置允许为null
val name: String? = null;
懒加载,被调用必须有值
val name: String? = null;

接口

关键字: interface , 默认是 public

interface Callback {
    fun callBackMethod(): Boolean
}

抽象类

关键字:abstract , 默认是 open,也就是 public 
abstract class Person  { 
}

继承

  • 抽象类
abstract class Person : Callback {  //实现了 Callback

    //在抽象类里面, 可以选择实现或者是不实行, 如果是普通类必须实现
//    override fun callBackMethod(): Boolean {
//        TODO("Not yet implemented")
//    }

    abstract fun getLayoutId(): Int;

    abstract fun initVIew();
}
  • 普通类
class Student : Person() {

    override fun getLayoutId(): Int {
        TODO("Not yet implemented")
    }

    override fun initVIew() {
        TODO("Not yet implemented")
    }

    override fun callBackMethod(): Boolean {
        TODO("Not yet implemented")
    }
}

POJO实体类

关键字: data

data class User (val name:String ,val age: Int, val set:Char, val isSHow: Boolean)

自动生成常用的函数

编译成java看看

public final class User {
   @NotNull
   private final String name;
   private final int age;
   private final char set;
   private final boolean isSHow;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final int getAge() {
      return this.age;
   }

   public final char getSet() {
      return this.set;
   }

   public final boolean isSHow() {
      return this.isSHow;
   }

   public User(@NotNull String name, int age, char set, boolean isSHow) {
      Intrinsics.checkNotNullParameter(name, "name");
      super();
      this.name = name;
      this.age = age;
      this.set = set;
      this.isSHow = isSHow;
   }

   @NotNull
   public final String component1() {
      return this.name;
   }

   public final int component2() {
      return this.age;
   }

   public final char component3() {
      return this.set;
   }

   public final boolean component4() {
      return this.isSHow;
   }

   @NotNull
   public final User copy(@NotNull String name, int age, char set, boolean isSHow) {
      Intrinsics.checkNotNullParameter(name, "name");
      return new User(name, age, set, isSHow);
   }

   // $FF: synthetic method
   public static User copy$default(User var0, String var1, int var2, char var3, boolean var4, int var5, Object var6) {
      if ((var5 & 1) != 0) {
         var1 = var0.name;
      }

      if ((var5 & 2) != 0) {
         var2 = var0.age;
      }

      if ((var5 & 4) != 0) {
         var3 = var0.set;
      }

      if ((var5 & 8) != 0) {
         var4 = var0.isSHow;
      }

      return var0.copy(var1, var2, var3, var4);
   }

   @NotNull
   public String toString() {
      return "User(name=" + this.name + ", age=" + this.age + ", set=" + this.set + ", isSHow=" + this.isSHow + ")";
   }

   public int hashCode() {
      String var10000 = this.name;
      int var1 = (((var10000 != null ? var10000.hashCode() : 0) * 31 + this.age) * 31 + this.set) * 31;
      byte var10001 = this.isSHow;
      if (var10001 != 0) {
         var10001 = 1;
      }

      return var1 + var10001;
   }

   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof User) {
            User var2 = (User)var1;
            if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age && this.set == var2.set && this.isSHow == var2.isSHow) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}

单例类(object)

object MyEngine {
    
    fun method() {
        println("单利class,methid函数")
    }
}

Kotlin写单例

class NetManager {

    object Holder {
        val instance = NetManager();
    }

    //派生字段, 相当于 java static 关键字
    companion object {

        fun getInstance(): NetManager = Holder.instance;
    }

    fun show(name: String) {
        println(name)
    }
}


fun main() {
    NetManager.getInstance().show("kt")
}

内部类 (inner)

class Test {

    val I = "AAAA"

    class Sub {
        fun show() {
//            print("拿到变量:${I}")  //拿不到 I ,  kotlin 不是类部类,而且嵌套类
        }
    }

    inner class Sub2 {
        fun show() {
            print("改成类部类 关键字  inner ${I}")
        }
    }
}

你可能感兴趣的:(Kotlin)