第一行代码 第三版 Kotlin部分笔记(1)

仅为个人笔记

目录

1、变量

2、函数(方法)

3、if条件语句

4、when条件语句

5、区间

..关键字

until关键字

6、for循环

使用step跳过区间内的元素       

使用downTo遍历降序区间

7、类与对象

构造函数

继承

接口

Java和Kotlin函数可见性修饰符对照表​编辑

数据类(data关键字)

单例类(object关键字)


1、变量

Kotlin中定义一个变量,只允许在变量前声明两种关键字:val和var。

val:用来声明一个不可变的变量,初始赋值之后不能重新赋值,对应Java中的final变量。

var:用来声明一个可变的变量,初始赋值之后可以被重新赋值,对应Java中的非final变量。

val a: Int = 10

Kotlin每一行代码的结尾是不用加分号的。

fun main() {

    var a: Int = 10

    a = a * 10

    println("a= " + a)

}

结果:

a = 100

2、函数(方法)

fun largerNumber(num1: Int, num2: Int): Int {
    return max(num1, num2)
}

       首先fun是定义函数的关键字,无论定义什么函数,都一定要使用fun来声明。

       紧跟在fun后面的是函数名。函数名后面紧跟着一对括号,里面可以声明该函数接收什么参数,参数的声明格式是“参数名: 参数类”,如果不想接收任何参数,就写一对空括号。

       参数括号后面的那部分是可选的,用于声明该函数会返回什么类型的数据,上述示例就表示该函数会返回一个Int类型的数据。如果函数不需要返回任何数据,这部分可以直接不写。

       最后两个大括号之间的内容就是函数体了,可以在这里编写一个函数的具体逻辑。上述代码中使用了一个max()函数,这是Kotlin提供的一个内置函数,它的作用就是返回两个参数中更大的那个数。

fun main() {
    val a = 37
    val b = 40
    val value = largerNumber(a, b)
    println("larger number is "+ value)
}

fun largerNumber(num1: Int, num2: Int): Int {
    return max(num1, num2)
}

结果:

larger number is 40

       当一个函数中只有一行代码时,Kotlin允许我们不必编写函数体,可以直接将唯一的一行代码写在函数定义的尾部,中间用等号连接即可。比如我们刚才编写的LargerNumber()函数就只有一行代码,于是可以将代码简化成如下形式:

fun largerNumber(num1: Int, num2: Int): Int = max(num1, num2)

       由于max()函数返回的是一个Int值,而我们在LargerNumber()函数的尾部又使用等号连接了max()函数,因此Kotlin可以推导出LargerNumber()函数返回的必然也是一个Int值,这样就不用再显式地声明返回值。

fun largerNumber(num1: Int, num2: Int) = max(num1, num2)

3、if条件语句

fun largerNumber(num1: Int, num2: Int): Int {
    var value = 0
    if (num1 > num2) {
        value = num1
    } else {
        value = num2
    }
    return value
}

       Kotlin中的if语句相比于Java有一个额外的功能,它是可以有返回值的,返回值就是if语句每
个条件中最后一行代码的返回值。

       仔细观察上述代码,你会发现value其实也是一个多余的变量,我们可以直接将if语句返回,这样代码将会变得更加精简。
       因此,上述代码就可以简化成如下形式:

fun largerNumber(num1: Int, num2: Int): Int {
    return if (num1 > num2) {
        num1
    } else {
        num2
    }
}

       当一个函数只有一行代码时,可以省略函数体部分,直接将这一行代码使用等号串连在函数定义的尾部。

fun largerNumber(num1: Int, num2: Int) = if (num1 >num2) num1 else num2

4、when条件语句

Kotlin中的when语句有点类似于Java中的switch语句,但它又远比switch语句强大得多。

fun getScore(name: String) = if (name == "Tom") {
    86
} else if (name == "Jim"){
    77
} else if (name == "Jack"){
    95
} else if (name == "Lily"){
    100
} else {
    0
}

当判断条件非常多的时候,就是应该考虑使用when语句的时候。

fun getScore(name: String) = when (name) {
    "Tom" -> 86
    "Jim" -> 77
    "Jack" -> 95
    "Lily" -> 100
    else -> 0
}

       when语句允许传入一个任意类型的参数,然后可以在wheen的结构体中定义一系列的条件,当你的执行逻辑只有一行代码时,{}可以省略。格式:

匹配值 -> { 执行逻辑 }

除了精确匹配之外,when语句还允许进行类型匹配。

fun checkNumber(num: Number) {
    when (num) {
        is Int -> println("number is Int")
        is Double -> println("number is Double")
        else ->println("number not support")
    }
}

       上述代码中,is关键字就是类型匹配的核心,它相当于Java中的instanceof关键字。由于checkNumber()函数接收一个Number类型的参数,这是Kotlin内置的一个抽象类,像Int、Long、Float、Double等与数字相关的类都是它的子类,所以这里就可以使用类型匹配来判断传入的参数到底属于什么类型。
       when语句的基本用法就是这些,但其实when语句还有一种不带参数的用法,虽然这种用法可能不太常用,但有的时候却能发挥很强的扩展性。

       举个例子,假设所有名字以Tom开头的人,他的分数都是86分,这种场景如果用带参数的when语句来写就无法实现,而使用不带参数的when语句就可以这样写:

fun getScore(name: String) = when {
    name.startsWith("Tom") -> 86
    name == "Jim" -> 77
    name == "Jack" -> 95
    name == "Lily" -> 100
    else -> 0
}

       注意,Kotlin中判断字符串或对象是否相等可以直接使用==关键字,而不用像Java那详调equals()方法。

5、区间

使用如下Kotlin代码来表示一个区间:

..关键字

//创建一个0到10的闭区间,它的数学表达方式是[0,10]
val range = 0..10

       上述代码表示创建了一个0到10的闭区间,这意味着0到10这两个端点都是包含在区间中的。其中,..是创建两端闭区间的关键字,在..的两边指定区间的左右端点就可以创建一个区间了。

until关键字

//创建一个0到10的左闭右开区间,它的数学表达方式是[0,10)
val range = 0 until 10

6、for循环

Java中另一种for-each循环被Kotlin进行了大幅度的加强,变成了for-in循环。

fun main() {
    for (i in 0..3) {
    println(i)
}

结果:

0
1
2
3

使用step跳过区间内的元素       

       默认情况下,for-in循环每次执行循环时会在区间范围内递增1,相当于Java for-i循环中i++的效果,而如果你想跳过其中的一些元素,可以使用step关键字:

//在遍历[0,5)这个区间的时候,每次执行循环都会在区间范围内递增2。
fun main() {
    for (i in 0 until 5 step 2) {
    println(i)
    }
}

结果:

0
2
4

使用downTo遍历降序区间

//创建一个降序的区间,可以使用downTo关键字。
fun main() {
    for (i in 3 downTo 1) {
        println(i)
    }
}

结果:

3
2
1
0

7、类与对象

//Kotlin中也是使用class关键字来声明一个类的。
class Person {
    var name = ""
    var age = 0
    fun eat(){
        println(name + " is eating. He is " + age + " years old.")
    }
}


fun main() {
    //Kotlin中实例化一个类的方式和Java是基本类似的,只是去掉了new关键字而已。
    val p = Person()  
    p.name = "Jack"
    p.age = 19
    p.eat()
}

结果:

Jack is eating. He is 19 years old.

构造函数

Kotlin将构造函数分成了两种:主构造函数和次构造函数。
       主构造函数将会是你最常用的构造函数,每个类默认都会有一个不带参数的主构造函数,当然
你也可以显式地给它指明参数。主构造函数的特点是没有函数体,直接定义在类名的后面即可。比如下面这种写法:

//主构造函数
class Person(val name: String, val age: Int) {
   ...
}

这表明在对Person类进行实例化的时候,必须传入构造函数中要求的所有参数。

val person = Person("Tom", 5)

       任何一个类只能有一个主构造函数,但是可以有多个次构造函数。次构造函数也可以用于实例化一个类,这一点和主构造函数没有什么不同,只不过它是有函数体的。Kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)。

class Person(val name: String, val age: Int) {
    //次构造函数是通过constructor关键字来定义的
   constructor(name: String) : this(name, 5) {
   }
   constructor() : this("Tom") {
   }
}

       这里我们定义了两个次构造函数:第一个次构造函数接收name参数,然后它又通过this关键字调用了主构造函数,并将age参数赋值成初始值;第二个次构造函数不接收任何参数,它通过调用第一个次构造函数,间接的调用了主构造函数。

person1 = Person()
person2 = Person("Jack")
person3 = Person("Jack", 19)

继承

第一步:使父类可继承。

      在Kotlin中任何一个非抽象类默认都是不可以被继承的,相当于Java中给类声明了final关键字。加上open关键字之后,我们就是在主动告诉Kotlin编译器,Person这个类是专门为继承而设计的,这样Person类就允许被继承了。

open class Person(val name: String, val age: Int) {
   ...
}

第二步:要让Student类继承Person类。在Java中继承的关键字是extends,而在Kotlin中变成了一个冒号,写法如下:

class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age){
    ...
}

       Person类后面的一对空括号表示Student类的主构造函数在初始化的时候会调用Person类的无参数构造函数,即使在无参数的情况下,这对括号也不能省略。

       注意,我们在Student类的主构造函数中增加name和age这两个字段时,不能再将它们声明成val,因为在主构造函数中声明成val或者var的参数将自动成为该类的字段,这就会导致和父类中同名的name和age字段造成冲突。因此,这里的name和age参数前面我们不用加任何关键字,让它的作用域仅限定在主构造函数当中即可。

//创建一个Student类的实例
val student = Student("a123", 5, "Jack", 19)

     那么接下来我们就再来看一种非常特殊的情况:类中只有次构造函数,没有主构造函数。

class Student : Person {
    constructor(name: String, age: Int) : super(name, age) {
}

Student类既然没有主构造函数,继承Person类的时候也就不需要再加上括号了。由于没有主构造函数,次构造函数只能直接调用父类的构造函数,上述代码也是将this关键字换成了super关键字。

接口

interface Study {
    fun readBooks()

    //Kotlin还增加了一个额外的功能:允许对接口中定义的函数进行默认实现。
    fun doHomework() {
        println("do homework default implementation.")
    }

    fun ageInformation() {
        println("I don't know how old he is.")
    }
}
//Kotlin用逗号代替java的implements用来实现接口
class Student(name: String, age: Int) : Person(name, age), Study {
    override fun readBooks() {
        println(name + " is reading.")
    }

    override fun ageInformation() {
        println(name + " is " + age + " years old.")
    }
}

       如果接口中的一个函数拥有了函数体,这个函数体中的内容就是它的默认实现。现在当一个类去实现Study接口时,只会强制要求实现readBooks()函数,而doHomework()函数则可以自由选择实现或者不实现,不实现时就会自动使用默认的实现逻辑。 

fun main(){
    val student = Student("Jack", 19)
    doStudy(student)
}
fun doStudy(study: Study) {
    study.readBooks()
    study.doHomework()
    study.ageInformation()
}

结果:

Jack is reading.
do homework default implementation.
Jack is 19 years old.

Java和Kotlin函数可见性修饰符对照表

数据类(data关键字)

构建一个手机数据类,字段就简单一点,只有品牌和价格这两个字段。

//Kotlin
data class Cellphone(val brand: String, val price: Double)
//当一个类中没有任何代码时,还可以将尾部的大括号省略路。

相当于

//java
public class Cellphone {
    String brand;
    double price;

    public Cellphone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Cellphone) {
            Cellphone other = (Cellphone) obj;
            return other.brand.equals(brand) && other.price == price;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return brand.hashCode() + (int) price;
    }

    @Override
    public String toString() {
        return "Cellphone(brand=" + brand + ", price=" + price + ")";
    }

}

       当在一个类前面声明了data关键字时,就表明你希望这个类是一个数据类,Kotlin会根据主构造函数中的参数帮你将equals()、hashCode()、toString()等固定且无实际逻辑意义的方法自动生成,从而大大减少了开发的工作量。

fun main( ){
    val cellphone1 = Cellphone("Samsung", 1299.99)
    val cellphone2 = Cellphone("Samsung", 1299.99)
    println(cellphone1)
    printin("cellphone1 equals cellphone2 " + (cellphone1 == cellphone2))
}

结果:

Cellphone(brand=Samsung, price=1299.99)
cellphone1 equals cellphone2 true

单例类(object关键字)

创建一个Singleton单例类

//Kotlin
object Singleton {
    fun singletonTest(){
    println("singletonTest is called.")
    }
}


//调用单例中的函数
Singleton.singletonTest()
//这种写法虽然看上去像是静态方法的调用,但其实Kotlin在背后自动帮我们创建Singleton类的实例,并且保证全局只会存在一个Singleton实例。

相当于

//Java
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public void singletonTest() {
        System.out.println("singletonTest is called.");
    }
}


//调用单例中的函数
Singleton singleton = Singleton.getInstance();
singleton.singletonTest();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值