kotlin教程(1)

最近在读《kotlin 实战》,这里做一下笔记,就当复习总结了,开头先附上官网文档的地址 https://www.kotlincn.net/
该篇文档主要讲述kotlin的基本要素,变量、函数、类,和Java之间的异同点。

函数和变量

Hello World 开始

public class First{
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

而kotlin中的代码就简单很多了

// kotlin默认的返回值就是Unit,即对应Java中void方法,所以下面两行的写法是等价的
// fun main(args: Array<String>): Unit {
fun main(args: Array<String>) {
    printlin("Hello World)
}

从这两段代码中,我们可以知道

  • 用关键字fun生命一个函数
  • 参数的类型生命实在名称后面,同理,变量的声明也是如此,eg. val a:Int = 10 (声明一个Int类型的变量,值为10)
  • 函数可以定义在最外层,不需要放置在类中
  • 数组就是类,kotlin没有声明数组类型的特殊语法,即 args:Array 等价 Java中的 String[] args
  • 使用println()是kotlin标准库(提供了许多比Java语法更简洁的包装)中的一个函数,代替了 System.out.println();
  • 行尾可以省略分号

函数

上面的函数没有返回任何值,如果需要返回一个有意义的结果,需要在方法后声明返回类型,如下

fun max(a: Int, b: Int): Int {
    return if (a > b) a else b
}

kotlin中没有三目运算符,可以使用上面的if else 语句来代替。kotlin中的if和Java中的if有点不一样,在kotlin中,if是表达式,而不是语句
** 语句和表达式的区别在于,表达式有值,并且能作为另一个表达式的的一部分使用,而语句则没有自己的值

上面的函数可以写的更加简单,因为函数体只有单个表达式。所以可以写成

fun max(a: Int, b: Int) = if (a > b) a else b   // 这边因为可以从函数体中推断出返回的值为Int,所以也可以省去返回类型
```kotlin
在kotlin中有很多可以通过类型推导而省去显示写出来的操作,后面我们还会遇到。

## 变量
kotlin中声明变量以val和var关键字开始,然后是变量名称,最后可以加上类型(不加也可以)
```kotlin
val str = "hello"
// 下面两行是等价的
var a:Int = 10
var a = 10
// 如果变量没有被初始化,则必须指定类型,如下所示
val b:Int
b = 22

val -> 不可变引用,对应java的final变量
var -> 可变引用,对应java中的普通变量
需要注意的是,是虽然var关键字运营变量改变自己的值,但是类型无法改变,和java一样,是强类型的。

var num = 10
num = "ffff"      // 错误,无法通过编译,类型不匹配

类和属性

kotlin中的类

/*java*/
public class Person{
    private String name;

    public String getName() {
        return name;
    }

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

在kotlin实现上述的代码只需要一行

class Person(var name:String)

或者可以写成下面这种类似java的写法

class Person{
    //默认实现了 getter 和 setter 方法
    var name:String = "我必须初始化" // 类中声明的属性必须得初始化,否则编译报错
}

我们可以使用idea自带的kotlin反编译,来看看他生成的字节码反编译后的样子

public final class Person {
   @NotNull
   private String name;

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

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.name = var1;
   }

   public Person(@NotNull String name) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
   }
}

这下看起来熟悉了吧

  • kotlin中默认的可见性修饰符是public,而且默认的class是不能被继承的,如果可以被继承,必须加上open关键字 ,eg. open class Person{}
  • kollin中可以使用data class XX{} 来生成一个pojo,和没有data相比,会多出toString和hashCode等方法

内部类

koltin 中默认是嵌套类( 对应 Java中的静态内部类)

区分内部类与嵌套类,很简单,内部类存储了外部类的引用,嵌套类却没有

class Outer {
    val name = "MyNameIsOuter"
    // inner说明是个内部类
    inner class Inner {
        fun printParent() {
            // 访问外部类成员时指明类作用域
            println(this@Outer.name)
        }
    }
}

fun main(args: Array<String>) {
  Outer().Inner().printParent()   // 输出: MyNameIsOuter
}

属性

声明一个属性的完整语法是
var [: ][= ]
[]
[]
其初始器(initializer)、getter 和 setter 都是可选的 。属性类型如果可以从初始器 (或者从其 getter 返回值,如下文所示)中推断出来,也可以省略。

kotlin中定义了属性,val的会生成getter方法,var的会生成 setter和getter方法,
当然我们也可以自己定义

class Square(var height: Int, var width: Int) {

    val isEqual: Boolean
        get() {
            return height == width
        }
}

像上面这种定义是不会生成一个isEqual的属性的,具体的可以了解一下kotlin的幕后属性

匿名内部类和接口

koltin使用对象表达式创建匿名内部类实例:

简单来说,下面这段代码中的object是创建内部类的语法,然后fun前面的override说明该方法是被覆写的。

window.addMouseListener(object: MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ……
    }                                                                                     
    override fun mouseEntered(e: MouseEvent) {
        // ……
    }
})

如果是函数式接口(只有单个抽象方法的Java接口,即java8中带有的 @FunctionalInterface注解的接口),可以如下使用lambda的表达式创建

// 里面的  println("clicked") 就是函数式接口的具体实现,是不是非常简洁
val listener = ActionListener { println("clicked") }
posted @ 2018-04-22 13:49  hinsy  阅读(309)  评论(0编辑  收藏  举报