Kotlin 入门学习笔记

以下内容纯粹为本人学习期间总结,如有错误之处烦请指正不胜感激😄

此次学习分享的内容均是Kotlin入门基础语法;协程,Anko,扩展属性等等还没涉及到

继承

  • Java
class A extends B { }
  • Kotlin
class A : B() {}

接口

  • Java
class A implements B, C {}
  • Kotlin
class A : B, C {}

override

Java 中是注解。重写父类方法,实现接口方法
Kotlin中成了类似关键字的东西。重写和实现自带了,不再是注解

  • Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
}
  • Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)
}

Object 类

  • JavaObject是所有类型的顶级父类
  • Kotlin中并没有Object,取而代之的是Any(),意义和Java中的Object一样。注意此处指的是大写OObject,非小写oobject

结扎关键字

  • JavaKotlin都不能继承自结扎类
  • Java中用final修饰的类不可被继承,并且Java中的类不声明为final的话则默认可被继承
  • Kotlin中则和Java相反,Kotlin中的类默认是被结扎的,不可被继承,除非使用了open关键字
  • Kotlin中如果某个类被声明为abstract,则不需要使用open进行修饰了,默认已经带上

实例化对象

  • Java
Person person = new Person(bug, 需求);
  • Kotlin
var person = Person(bug, 需求)

打印日志

  • Java
System.out.print("打印日志");
System.out.println("打印日志");
  • Kotlin
print("打印日志")
println("打印日志")

常量与变量

  • Java
String name = "Hello Java";
final String name = "Hello 结扎过的 Java";
  • Kotlin
var name = "Hello Kotlin"
val name = "Hello 结扎过的 Kotlin"

null声明

  • Java
String otherName;
otherName = null;
  • Kotlin
//在类型后面跟英文问号代表此变量可空
var otherName : String?
otherName = null

空判断

  • Java
if (text != null) {
    int length = text.length();
}
  • Kotlin
text?.let {
    val length = text.length
}
// 简单写法
val length = text?.length

字符串拼接

  • Java
String firstName = "ja";
String lastName = "va";
String message = "名字是: " + firstName + " " + lastName;
  • Kotlin
val firstName = "Ko"
val lastName = "tlin"
val message = "名字是: $firstName $lastName"

换行

  • Java
String text = "第一行\n" +
              "第二行\n" +
              "第三行";
  • Kotlin
//又叫多行文本字符串
val text = """
        |第一行
        |第二行
        |第三行
        """.trimMargin()
//trimMargin()方法是Kotlin自己的,用于替换掉字符串中的指定符号,点击查看源码可知默认值是"|",所以我们可以依照自己的需求来进行替换

val text = """
        >First Line
        |Second Line
        >Third Line
        """.trimMargin(">")
//这样就只会替换掉第一行和第三行前面的大于符号

三目运算符

  • Java
String text = x > 5 ? "x > 5" : "x <= 5";
  • Kotlin
val text = if (x > 5)
              "x > 5"
           else "x <= 5"

//简单写法
var s: String? = null
var text = s ?: "空了"  //s为空么?不为空返回自己,为空返回"空了"

操作符

  • java
final int andResult  = a & b;
final int orResult   = a | b;
final int xorResult  = a ^ b;
final int rightShift = a >> 2;
final int leftShift  = a << 2;
  • Kotlin
val andResult  = a and b
val orResult   = a or b
val xorResult  = a xor b
val rightShift = a shr 2
val leftShift  = a shl 2

类型判断和转换 (声明式)

  • Java
if (object instanceof Car) {
}
Car car = (Car) object;
  • Kotlin
if (object is Car) {
}
var car = object as Car

类型判断和转换 (隐式)

  • Java
if (object instanceof Car) {
   Car car = (Car) object;
}
  • Kotlin
if (object is Car) {
   var car = object // smart casting
}

多重条件

  • Java
if (score >= 0 && score <= 300) { }
  • Kotlin
if (score in 0..300) { }

更灵活的case语句

  • Java
int score = // some score;
String grade;
switch (score) {
    case 10:
    case 9:
        grade = "Excellent";
        break;
    case 8:
    case 7:
    case 6:
        grade = "Good";
        break;
    case 5:
    case 4:
        grade = "OK";
        break;
    case 3:
    case 2:
    case 1:
        grade = "Fail";
        break;
    default:
        grade = "Fail";
}
  • Kotlin
var score = // some score
var grade = when (score) {
    9, 10 -> "Excellent"
    in 6..8 -> "Good"
    4, 5 -> "OK"
    in 1..3 -> "Fail"
    else -> "Fail"
}

for循环

  • Java
for (int i = 1; i <= 10 ; i++) { }

for (int i = 1; i < 10 ; i++) { }

for (int i = 10; i >= 0 ; i--) { }

for (int i = 1; i <= 10 ; i+=2) { }

for (int i = 10; i >= 0 ; i-=2) { }

for (String item : collection) { }

for (Map.Entry<String, String> entry: map.entrySet()) { }
  • Kotlin
for (i in 1..10) { }

for (i in 1 until 10) { }

for (i in 10 downTo 0) { }

for (i in 1..10 step 2) { }

for (i in 10 downTo 1 step 2) { }

for (item in collection) { }

for ((key, value) in map) { }

更方便的集合操作一

  • Java
final List<Integer> listOfNumber = Arrays.asList(1, 2, 3, 4);

final Map<Integer, String> keyValue = new HashMap<Integer, String>();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");

// Java 9
final List<Integer> listOfNumber = List.of(1, 2, 3, 4);

final Map<Integer, String> keyValue = Map.of(1, "Java",
                                             2, "Kotlin",
                                             3, "Scala",
                                             4, "Swift");
  • Kotlin
val listOfNumber = listOf(1, 2, 3, 4)
val keyValue = mapOf(1 to "Java",
                     2 to "Kotlin",
                     3 to "Scala",
                     4 to "Swift")

更方便的集合操作二

  • Java
List<String> list = new ArrayList();
list.add("Java");
list.add("Kotlin");
list.add("Scala");
list.add("Swift");

Map<Integer, String> map = new HashMap();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");
  • Kotlin
var list = mutableListOf<String>()
list.add("Java")
list.add("Kotlin")
list.add("Scala")
list.add("Swift")

var map = mutableMapOf<Int, String>()
map.put(1, "Java")
map.put(2, "Kotlin")
map.put(3, "Scala")
map.put(4, "Swift")


遍历

  • Java
// Java 7 和以前
for (Car car : cars) {
  System.out.println(car.speed);
}

// Java 8+
cars.forEach(car -> System.out.println(car.speed));

// Java 7 和以前
for (Car car : cars) {
  if (car.speed > 100) {
    System.out.println(car.speed);
  }
}

// Java 8+
cars.stream().filter(car -> car.speed > 100).forEach(car -> System.out.println(car.speed));
  • Kotlin
cars.forEach {
    println(it.speed)
}

cars.filter { it.speed > 100 }
      .forEach { println(it.speed)}

方法定义

  • Java
void doSomething() {
   
}

void doSomething(int... numbers) {
   
}
  • Kotlin
fun doSomething() {
   
}

fun doSomething(vararg numbers: Int) {
   
}

带返回值的方法

  • Java
int getScore() {
  
   return score;
}
  • Kotlin
fun getScore(): Int {
   
   return score
}

//可直接在方法后返回
fun getScore(): Int = score

无结束符号

  • Java
int getScore(int value) {
   
    return 2 * value;
}
  • Kotlin
fun getScore(value: Int): Int {
   
   return 2 * value
}

//可直接在方法后返回
fun getScore(value: Int): Int = 2 * value

constructor 构造器

  • Java
public class Utils {

    private Utils() { 
     
    }
  
    public Utils(Int i ,String s){
      
    }
    
}
  • Kotlin
class Utils constructor(i: Int, s: String) {
    //这种方式的构造器是显示构造器,声明类的时候定好构造方法,实例化的时候必须按照参数列表进行实例化
  var utils = Utils(1, "")
}

class Utils (i: Int, s: String) {
    //上面的方式可省略 constructor 关键字
  var utils = Utils(1, "")
}

class Utils {
    constructor(i: Int, s: String)
    //上面同样可以写成这种样子,构造函数单独写进类里面
  var utils = Utils(1, "")
}


class Utils private constructor(i: Int, s: String) {
    //如果 constructor 前面有修饰符,则不能省略
  var utils = Utils()
}

class Utils private constructor() {
    constructor(i: Int, s: String) : this() {
        //这种声明表示我们有一个私有的构造方法,无参的,也可以有参,自己定义就好;然后我们公开了一个有参的构造方法供外部进行实例化
      var utils = Utils(1, "")
    }
}

class Utils constructor(i: Int = 2, s: String = "") {
    //如果构造方法中给定了默认值,那么在实例化对象的时候可以不传入参数,不传的话实例化出来的对象默认参数就是构造方法中的参数
  var utils = Utils()
  var utils = Utils(1)
  var utils = Utils("")
  var utils = Utils(1, "")
}

class Utils constructor(i: Int, s: String = "") {
    //但如果参数列表中有那种没有给定值的变量时,实例化时必须要将他们都传入构造方法
  var utils = Utils(1)
  var utils = Utils(1, "")
}


//引申内容,方法重载,注意和下面的 Kotlin 扩展函数区别开
class MainActivityKotlin {
  
  override fun onCreate(saveInstance: Bundle?) {
      super.onCreate(savedInstanceState)
        makeToast()
        makeToast("test")
        makeToast(time = Toast.LENGTH_LONG)
        makeToast("test", Toast.LENGTH_LONG)
        makeToast(msg = "test", time = Toast.LENGTH_LONG)
    }

    fun makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(this, msg, time).show()
    }
}

Kotlin 扩展函数

  • Kotlin
//扩展函数一般用在工具类的封装上,可以对现有的函数在不继承的情况下进行扩展
//object 声明下面会讲到
//扩展函数一般写法是,fun 关键字 加上要扩展的类的类名,以及方法名
object Utils {

    fun Activity.makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(this, msg, time).show()
    }
}

//调用时如下
//从调用处的包引入`import com.danlu.kotlindemo.Utils.makeToast`可以知道,扩展函数实际上是以静态被引入的,事实上它是静态解析的
//除了扩展函数,还有扩展属性
class MainActivityKotlin : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        makeToast()
        makeToast("test")
        makeToast(time = Toast.LENGTH_LONG)
        makeToast("test", Toast.LENGTH_LONG)
        makeToast(msg = "test", time = Toast.LENGTH_LONG)

    }
}

Get Set 构造器

  • Java
public class Developer {

    private String name;
    private int age;

    public Developer(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Developer developer = (Developer) o;

        if (age != developer.age) return false;
        return name != null ? name.equals(developer.name) : developer.name == null;

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    @Override
    public String toString() {
        return "Developer{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • Kotlin
data class Developer(val name: String, val age: Int)

静态

  • Java
public class Utils {

    private Utils() { 
    }
    
    public static int getDBVersion() {
        return CURRENT_DB_VERSION;
   }
}

int db_verison = Utils.getDBVersion();
  • Kotlin

Kotlin中使用object修饰静态类,被修饰的类,可以使用类名.方法名的形式调用

object Utils {

    fun getDBVersion(): Int {
        return CURRENT_DB_VERSION
    }

}

var db_verison = Utils.getDBVersion()

Kotlin中使用companion object修饰静态方法,称为伴生对象,可以使用类名.方法名的形式调用

class Utils {

    companion object {
        fun getDBVersion(): Int {
            return CURRENT_DB_VERSION
        }
    }
}

var db_verison = Utils.getDBVersion()

权限修饰符

Java

  • public 对所有类可见
  • default 在同一包内可见,不写默认default
  • protected 对同一包内的类和所有子类可见
  • private 在同一类内可见

Kotlin

  • public 凡是能够访问到这个类的地方, 同时也能访问这个类的public成员,不写默认是public
  • internal 在module之内, 凡是能够访问到这个类的地方, 同时也能访问到这个类的internal成员
  • protected 与private一样, 另外在子类中也可以访问
  • private 表示只在这个类(以及它的所有成员)之内可以访问,不会自动生成getter setter方法

标签(@)

  • Java
loop:
for (int i = 0; i < 100; i++) {
    loop1:
    for (int j = 0; j < 100; j++) {
        if (i == 3) { 
            continue loop1;
        } else if(i == 5) {
            continue loop;
        } else {
            break loop1;
        }
    }
}
  • Java中的标签我们用的极少,它主要是用来控制流程语句的执行,continuebreak。用法是:在语句内部需要continuebreak的地方,在控制关键字后跟上你想控制的某个循环。简单地说就是,一个循环一组标签,起始和终止位置标签内容一致。在循环内部,任意地方可以控制其他循环。为了方便跳转到指定位置

  • 在循环开始之前用自定义的名字加上英文冒号作为起始点,然后书写循环语句loop:循环语句体...continue/break loop;


  • Kotlin

val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
ints.forEach foreach@ {
    if (it == 0) return@foreach
    print(it)
}
  • 由于Kotlin中几乎万物都是表达式,所以会有方法后直接跟运算体的写法。Kotlin中的标签和Java中大同小异,只不过在循环控制上多了return,用来指定:在指定位置返回,上面的代码就说明在 it== 0时返回,不打印,所以打印结果是 123456
  • 另外Kotlin中的标签还可以用在this关键字上。Java中我们通常有XXXActivity.this的写法,用来代指XXXActivity这个引用,Kotlin中写法是this@XXXActivity

init代码块

class Test public constructor(val i: Int) {
  
    // 只对主构造方法生效
    init {
      
    }

    constructor(i: Int, s: String) : this(i) {
      
    }

    fun xxx() {

    }
}

上述代码中,定义了Test类的两个构造方法,参数列表不同;实例化时可以:

val test = Test(1)
val test1 = Test(1, "")

而某些操作可能需要在默认/主构造方法中进行初始化,也就是单参数的构造方法中,所以这时候就有init代码块;Kotlin主构造函数不能包含任何的代码,所以初始化的代码可以放到init块中进行


lateinit 和 by lazy

对象/变量可以通过依赖注入来初始化, 或者在单元测试的setup方法中初始化。 这种情况下,我们并不能直接在构造方法内提供一个非空构造器,但我们使用时依然想要避免对象/变量的空问题,所以。。。

  • lateinit意思是延迟初始化,只有当变量/对象被声明为var时才可使用
  • by lazy意思是懒初始化,只有当变量/对象被声明为val时才可使用
// by lazy 使用方式后面跟大括号,里面进行对象/变量的实例化/赋值
// by lazy 只会在第一次使用 danluUtil / name / id 的时候才会创建对象或者实例初始化变量
// 和 java 中的懒汉式单例一样,使用时候判空,不为空直接返回对象,为空的话实例化对象再返回
val danluUtil by lazy {
     DanluUtil(i, j)
}
val name by lazy {"名字"}
val id by lazy {1}


// lateinit 使用方式在 var 前面加上 lateinit 即可,后面跟上变量和变量类型
// lateinit 声明的变量/对象,不能为空,也不能被立即初始化:比如下面两种方式都是不允许的:
// lateinit var danluUtil: DanluUtil = DanluUtil(i, j)
// lateinit var danluUtil: DanluUtil?
// 大致来说,这段代码将变量的初始化与定义分离开了
// 使用场景包括但不限于依赖注入框架(例如 Dagger2),那些预先声明的变量也无法成功初始化。在这种情况下,必须使用 lateinit 关键字确保变量在稍后将被初始化
lateinit var danluUtil: DanluUtil
// 声明完毕后在需要用到的地方进行初始化:
danluUtil = DanluUtil(i, j)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容