2021-11-18
浅谈KotlinKotlin由JetBrains公司开发与设计,2011年发布第一个版本,2012年开源。2017年goole正式成为Android一级开发语言。编译型语言和解释性语言,class文件,java虚拟机语法更简洁,代码量减少50%甚至更多,语法更高级,安全性更高,几乎杜绝了空指针这个全球崩溃率最高的的异常。和JAVA100%兼容,可以直接调用JAVA写的代码和第三方库。变量和函数1)
浅谈Kotlin
- Kotlin由JetBrains公司开发与设计,2011年发布第一个版本,2012年开源。2017年goole正式成为Android一级开发语言。
- 编译型语言和解释性语言,class文件,java虚拟机
- 语法更简洁,代码量减少50%甚至更多,语法更高级,安全性更高,几乎杜绝了空指针这个全球崩溃率最高的的异常。和JAVA100%兼容,可以直接调用JAVA写的代码和第三方库。
- 变量和函数
1)变量
Val和var,出色的类推导机制,摒弃了Java的基本数据结构,全部使用对象数据类型,Int变成了一个类。为了解决java中final没有被合理使用的问题,优先使用val来声明变量。
val a: Int = 1
val b = 1 // 系统自动推断变量类型为Int
var x = 5 // 系统自动推断变量类型为Int
x += 1 // 变量可修改
末尾不加分号
2)函数
fun是定义函数的关键字
fun sum(a: Int, b: Int): Int { // Int 参数,返回值 Int
return a + b
}
- 条件语句
1) if条件语句
fun largerNumber(num1:Int,num2:Int):Int {
var value=0
if (num1>num2){
value=num1
}else{
value=num2
}
return value
}
有返回值,返回值是if语句每个条件中最后一行代码的返回值
fun largerNumber(num1:Int,num2:Int):Int {
var value= if (num1>num2){
num1
}else{
num2
}
return value
}
value也可以省略,直接返回if语句
fun largerNumber(num1:Int,num2:Int):Int {
return if (num1>num2){
num1
}else{
num2
}
}
当函数体只有一行代码时,可以省略函数体部分,直接用等号连在函数定义的尾部
fun largerNumber(num1:Int,num2:Int):Int= if (num1>num2){
num1
}else{
num2
}
}
fun largerNumber(num1:Int,num2:Int) = if(num1>num2) num1 else num2
2) when条件语句
java中switch只能传入整型,字符串或者短于整型的变量作为条件,而且要在每种case条件后加一个break.
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x 不是 1 ,也不是 2")
}
}
还允许内容匹配
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")//is 相当于instanceof
else -> false
}
不带参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支
fun main(args: Array<String>) {
val items = setOf("apple", "banana", "kiwi")
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
}
- 循环语句
While和Java一样
For语句
For -i被摒弃,for-each得到加强变为for-in
区间概念:
闭区间:0…10
开区间:0 until 10
降序:10 downTo 1 step 2
fun main(args: Array<String>) {
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
}
- 类与对象
创建实例
val site = Runoob() // Kotlin 中没有 new 关键字
继承与构造函数
Kotlin 中所有类都继承该 Any 类,它是所有类的超类,对于没有超类型声明的类是默认超类,默认所有非抽象类都是不可被继承的,这点和val很像,如果要想让他可以被继承,必须在前面加上open
由extends变成了:
open class Base(p: Int) // 定义基类
class Derived(p: Int) : Base(p)
继承时不同于java,要在基类后加()——主构造函数,次构造函数
主构造函数:默认没有参数,当然也可以指明参数,没有函数体
open class Person(var name : String, var age : Int){// 基类
}
class Student(name : String, age : Int, var no : String, var score : Int) : Person(name, age) {
}
// 测试
fun main(args: Array<String>) {
val s = Student("Runoob", 18, "S12346", 89)
println("学生名: ${s.name}")
println("年龄: ${s.age}")
println("学生号: ${s.no}")
println("成绩: ${s.score}")
}
如果想在主构造函数中编写逻辑,使用init结构体。
子类的构造函数必须调用父类的构造函数——子类调用父类哪个构造函数通过()来指定。
次构造函数
几乎用不到,通过constructor来定义
接口
Java和kotlin都是单继承语言只能有一个父类,但是却能有多个接口。Kotlin统一使用:,中间用逗号分隔,接口后面不用加(),因为他没有构造函数可以使用
可见性符修饰
Java: public, private,protect,default(默认)
Kotlin: public(默认), private,protect,internal
8. 数据类和单例类
在一个规范的系统架构中,数据类通常占据着非常重要的角色,用于将服务器或者数据库中的数据映射到内存当中,为编程逻辑提供数据模型支持
Kotlin 可以创建一个只包含数据的类,关键字为 data:
data class User(val name: String, val age: Int)
无需重写equals() / hashCode()、toString()
单列类
私有化构造函数,避免外部直接创建,然后对外暴露静态方法用于获取当前对象实例
Object修饰
Object Singleton{}
9. Lambda编程
1) 集合创建与遍历
val mList = listOf<Int>(1, 2, 3)
val mList = mutableListOf<Int>(1, 2, 3)
val mList = setOf<Int>(1,2,3)
val mList = mutableSetOf<Int>(1,2,3)
val mList = mapOf("key1" to 1, "key2" to 2)
val mList = mutableMapOf("key1" to 1, "key2" to 2)
2) Lambda表达式:可以作为参数传递的代码
Val list=listof(“apple”,”banana”,”orange”,”pear”,”peach”)
Val lamda={fruit:String->fruit.length}
Val maxLengthFruit=list.maxBy(lamda)
Val maxLengthFruit=list.maxBy({fruit:String->fruit.length})
当Lambda表达式是函数的最后一个参数时,可以移到函数括号外面
Val maxLengthFruit=list.maxBy(){fruit:String->fruit.length}
当Lambda表达式是函数的唯一一个参数时,可以省略函数括号
Val maxLengthFruit=list.maxBy{fruit:String->fruit.length}
Lambda表达式大多时候不需要声明函数类型
Val maxLengthFruit=list.maxBy{fruit ->fruit.length}
当Lambda参数列表只有一个参数时,可以省略函数括号
Val maxLengthFruit=list.maxBy{it. length}
Filter过滤。Any,all
Kotlin使用java函数式API,在kotlin调用一个Java方法,且方法接受一个Java单抽象方法接口参数,就可以使用。
public interface Runnable{
void run();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread is ruuning");
}
}).start();
Kotlin代码舍弃了new关键字,创建匿名内部类实例不能使用new了,改用object关键字
Thread(object :Runnable{
override fun run() {
println("Thread is running")
}
}).start()
简化如下,首先不用显式重写run方法,因为Kotlin知道Runnable后面的Lambda表达式是要在run方法中实现内容。
Thread(Runnable {
println("Thread is running")
}).start()
另外,如果一个Java方法的参数列表不存在一个以上Java单抽象方法接口参数,我们可以对接口名进行省略。
Thread({
println("Thread is running")
}).start()
最后,若此Lambda表达式是最后一个参数,可将表达式移到括号外面,因为方法只有唯一一个参数,括号也可以省略,最后的代码如下所示。
Thread({
println("Thread is running")
}).start()
这种其实很常见,Android中有一个常用的点击事件接口onClickListener,其定义如下。
public interface OnClickListener{
void onClick(View v)
}
此接口是单抽象方法接口,那么按钮button实例在点击事件注册时用Java可以这么写。
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
}
});
用Kotlin实现同样的功能可以使用函数式API写法对代码进行简化。代码精简很多。
button.setOnClickListener{}
Kotlin将空指针异常检查提前到编译时期而非运行时期,因此几乎杜绝了空指针异常。
fun doStudy(study: Study) {
study.readBooks()
study.doHomeWork()
}
eg:Int表示不为空的整型,Int?表示可为空的整型
1. fun doStudy(study: Study?) {
2. if (study != null){
3. study.readBooks()
4. study.doHomeWork()
5. }
6. }
?.操作符,其是当对象不为空时正常调用的方法,当对象为空时则什么都不做
?:操作符,其是左右两边都接受一个表达式,如果左边表达式的结果不为空就返回左边表达式的值,否则返回右边表达式的值。
fun getTextLength(text: String?): Int {
1. if (text != null) {
2. return text.length
3. }
4. return 0
使用!!.加在对象后面使得强行通过编译,但不建议
调用length字段需使用?.操作符,进而判断是不是为零。
fun getTextLength1(text: String?) = text?.length ?: 0
参考:第一含代码
更多推荐
所有评论(0)