Kotlin入门学习(非常详细),从零基础入门到精通,看完这一篇就够了(4)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

程序运行时,解释器会将源码一行一行实时解析成二进制再执行。例如JS,Python

优点:平台兼容性好,安装对应的虚拟机即可运行。

缺点:运行时需要解释执行,效率较低。

Java的语言类型

java准确来说属于混合型语言,但更偏向于解释型。

编译java存在JITAOTJIT即时编译将可将热点代码直接编译成机器码,AOT预先编译可再安装时把代码编译成机器码

解释java运行时需编译成class文件,java虚拟机再解释执行.class

Kotlin的运行原理

java虚拟机只认class文件, 虚拟机不会关心classjava文件编译来的,还是其他文件编译来的。那此时我们创造一套自己的语法规则,再做一个对应的编译器,,则可让我们的语言跑在java虚拟机上。Kotlin则是此原理,运行前会先编译成class,再供java虚拟机运行。

创建Kotlin项目

打开android studio,在选择语言时,选择Kotlin

在包下创建kotlin文件

创建File命名为HelloWorld

敲入下面代码则可运行打印Hello World!

package com.hbsd.demo

fun main() {
println(“Hello World!”)
}

运行结果如下:

下面进入语法学习

语法

变量

变量的声明

Kotlin使用var,val来声明变量,注意:Kotlin不再需要;来结尾

var 可变变量,对应java非final变量

var b = 1

val不可变变量,对应javafinal变量

val a = 1

两种变量并未声明类型,这是因为Kotlin存在类型推导机制,上述的a,b会默认为Int。假设想声明具体类型,则需下面的方式

var c: Int = 1

基本类型

Kotlin不再存在基本类型,将全部使用对象类型

Java基本类型Kotlin对象类型对象类型说明
intInt整型
longLong长整型
shortShort短整型
floatFloat单精度浮点型
doubleDouble双精度浮点型
booleanBoolean布尔型
charChar字符型
byteByte字节型
var和val的本质区别

打开Kotlin对应的Java文件

再点击下方按钮

则可查看对应的Java文件

public final class HelloWorldKt {
private static final int a = 1;
private static int b = 2;
private static int c = 10;


}

发现val a对应的为finalvar bvar c 对应的为非final

Kotlin此设计的原因则是防止非final的滥用,若一个变量永远不被修改则有必要给其加上final,使其他人看代码时更好理解。

后期我们写代码时则可先使用val,若真的需要修改再改为var

函数

函数的声明

无参无返回值

fun test() {
}

有参有返回值

参数的类型需要写在形参名后面中间使用:连接多个参数使用,分割",“返回值使用”:"拼接

fun add(a: Int, b: Int): Int {
return a + b
}

声明技巧

当函数体只有一行代码时可直接使用下面方式声明方法

fun add (a: Int, b: Int): Int = a + b

Kotlin存在类型推导,返回值类型也可省略

fun add (a: Int, b: Int) = a + b

函数的调用

fun main() {
test()
println(add(1, 2))
}

//运行结果
//test
//3

if语句

Kotlin中的选择控制有两种方式。ifwhen

if

Javaif区别不大,实现一个返回最大值的函数

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

Kotlin的if可以包含返回值,if语句的最后一行会作为返回值返回

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

上述我们说过一行代码可省略返回值

fun max(a: Int, b: Int) = if (a > b) a else b

查看对应的Java文件,其上述实现都与下面代码等价

public static final int max(int a, int b) {
return a > b ? a : b;
}

when

实现一个查询成绩的函数,用户传入名字,返回成绩级别

if实现

Kotlinif语句必须要有else,不然会报错

fun getScore(name: String) = if (name == “Tom”) “不及格”
else if (name == “Jim”) “及格”
else if (name == “Pony”) “良好”
else if (name == “Tony”) “优秀”
else “名字非法”

Kotlin==等价于Javaequals比较的时是对象里的内容, === 等价于Java==,比较的为对象的引用。

when实现

也必须实现else,否则报错

fun getScore(name: String) = when(name) {
“Tom” -> “不及格”
“Jim” -> “及格”
“Pony” -> “良好”
“Tony” -> “优秀”
else -> “名字非法”
}

when支持参数检查

fun checkNumber(num: Number) {
when (num) {
is Int -> println(“Int”)
is Double -> println(“Double”)
else -> println(“others”)
}
}

when可不传递形参

使用Boolean使when更加灵活

fun getScore(name: String) = when {
name == “Tom” -> “不及格”
name == “Jim” -> “及格”
name == “Pony” -> “良好”
name == “Tony” -> “优秀”
else -> “名字非法”
}

-> 后不仅可以只执行一行代码,可以多行,看一个比较复杂的例子:

fun getScore(name: String) = when {
//若name以Tom开头则命中此分支
name.startsWith(“Tom”) -> {
//处理
println(“你好,我是Tom开头的同学”)
“不及格”
}
name == “Jim” -> “及格”
name == “Pony” -> “良好”
name == “Tony” -> “优秀”
else -> “名字非法”
}

循环语句

Kotlin有两种循环方式,whilefor-inwhilejava中的while没有区别,for-in是对Java for-each的加强,Kotlin舍弃了for-i的写法

while不再赘述,在学习for-in之前需要明确一个概念-区间

val range = 0…10 //区间代表[0,10]

for-in需借助区间来使用

fun main() {
val range = 0…10
for (i in range) { //也可直接for (i in 0…10)
println(i)
}
//输出结果为 从0打印到10
}

0..10 代表双闭区间,如果想使用左闭右开呢,需要借助until关键字

fun main() {
for (i in 0 until 10) {
println(i)
}
//输出结果为 从0打印到9
}

上述实现是逐步进行相当于i++Kotlin也支持跳步

fun main() {
for (i in 0 until 10 step 2) {
println(i)
}
//输出结果为0,2,4,6,8
}

上述实现都是升序,Kotlin也可降序循环

fun main() {
for (i in 10 downTo 1) {
println(i)
}
//输出结果为10 - 1
}

for-in不仅可对区间进行遍历,还可对集合进行遍历,后续在集合处进行展示。

类和对象

类的创建和对象的初始化

在创建页面选择Class创建

创建Person类,并声明nameage,创建printInfo方法

class Person {
var name = “”
var age = 0
fun printInfo() {
println(name +"'s age is " + age)
}
}

main方法中声明一个Person对象并调用printInfo方法

fun main() {
val person = Person()
person.name = “zjm”
person.age = 20
person.printInfo()
}
//结果如下zjm’s age is 20

继承

声明Student类继承PersonKotlin中继承使用**:**,后接父类的构造,为什么需要构造后续讲解

class Student : Person(){ //此时Person报错
var number = “”
var grade = 0
fun study() {
println(name + “is studying”)
}
}

Person类当前不可继承,查看Person对应的java文件

public final class Person {

}

Person类为final不可被继承,因此需借助open关键字

只需在Person类前加上open

open class Person {

}

此时Personjava文件变为

public class Person {

}

此时Student将不再报错

构造

构造分为主构造和此构造

主构造

主构造直接写在类后面

修改Student

class Student(val number: String, val grade: Int) : Person(){

}

在创建Student对象时,如下创建

val student = Student(“1234”, 90)

因之前Person还有nameage,下面修改Person类的主构造

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

}

此时Student报错,因为继承Person时,后边使用的是Person()无参构造,上面我们修改了Person的构造,则不存在无参构造了。

再修改Student

class Student(name: String, age: Int, val number: String, val grade: Int) : Person(name, age){

}

此时不在报错,声明方式如下

val student = Student(“zjm”, 20, “1234”, 90)

在构造时需要进行特殊处理怎么办,Kotlin提供了init结构体,主构造的逻辑可在init中处理

open class Person(val name: String, val age: Int) {
init {
println(“name is” + name)
println(“age is” + age)
}
}

上述修改都为主构造,那如果类想有多个构造怎么办,此时需借助次构造

次构造

此时实现Student的另外两个构造

三个参数的构造,nameagenumbergrade不传参默认为``0

无参构造,字符串默认为"",int默认为0

class Student(name: String, age: Int, val number: String, val grade: Int) : Person(name, age){
constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {

}
constructor() : this(“”, 0, “”, 0) {

}

}

创建如下:

fun main() {
val student1 = Student(“zjm”, 20, “123”, 90)
val student2 = Student(“zjm”, 20, “123”)
val student3 = Student()
}

无主构造

若类不使用主构造,则后续继承类也不需要使用构造即可去掉继承类的(),次构造可以调用父类构造super进行初始化,但是次构造的参数在其他地方无法引用

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

}
fun study() {
//name,age可使用
println(name + “is studying”)
//使用number则会报错,若number是主构造的参数则可引用
//println(number) 报红
}
}

接口

接口的定义

Java中的接口定义类似

interface Study {
fun study()
fun readBooks()
fun doHomework()
}

接口的继承

继承接口只需在后用","拼接,需实现Study声明的全部函数

class Student(name: String, age: Int, val number: String, val grade: Int) : Person(name, age), Study{

override fun study() {
TODO(“Not yet implemented”)
}

override fun readBooks() {
TODO(“Not yet implemented”)
}

override fun doHomework() {
TODO(“Not yet implemented”)
}
}

Kotlin支持接口方法的默认实现,JDK1.8以后也支持此功能,方法有默认实现则继承类无需必须实现此方法

interface Study {
fun study() {
println(“study”)
}
fun readBooks()
fun doHomework()
}

权限修饰符

JavaKotlin的不同如下表所示:

修饰符JavaKotlin
public所有类可见所有类可见(默认)
private当前类可见当前类可见
protected当前类,子类,同包下类可见当前类,子类可见
default同包下类可见(默认)
internal同模块下的类可见

Kotlin引入internal,摒弃了default

使用:

类上

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

变量上

private val value = 1

方法上

private fun test() {

}

数据类和单例类

数据类

数据类则只处理数据相关,与Java Bean类似,通常需要实现其getsethashCodeequalstoString等方法

下面实现UserBean,包含idnamepwd属性

Java编写入如下:

public class UserBean {
private String id;
private String name;
private String pwd;

public UserBean() {

}

public UserBean(String id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserBean userBean = (UserBean) o;
return Objects.equals(id, userBean.id) && Objects.equals(name, userBean.name) && Objects.equals(pwd, userBean.pwd);
}

@Override
public int hashCode() {
return Objects.hash(id, name, pwd);
}

@Override
public String toString() {
return “UserBean{” +
“id='” + id + ‘’’ +
“, name='” + name + ‘’’ +
“, pwd='” + pwd + ‘’’ +
‘}’;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

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

public String getPwd() {
return pwd;
}

public void setPwd(String pwd) {
this.pwd = pwd;
}
}

Kotlin编写此类将变得非常简单,新建一个kt文件,选择如下:

一行代码即可搞定,Kotlin会自动实现上述方法。

data class UserBean(val id: String, val name: String, val pwd: String)

若无data关键字,上述方法(hashCodeequalstoString)无法正常运行,去掉data查看Kotlin对应的java文件:

public final class UserBean {
@NotNull
private final String id;
@NotNull
private final String name;
@NotNull
private final String pwd;

@NotNull
public final String getId() {
return this.id;
}

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

@NotNull
public final String getPwd() {
return this.pwd;
}

public UserBean(@NotNull String id, @NotNull String name, @NotNull String pwd) {
Intrinsics.checkNotNullParameter(id, “id”);
Intrinsics.checkNotNullParameter(name, “name”);
Intrinsics.checkNotNullParameter(pwd, “pwd”);
super();
this.id = id;
this.name = name;
this.pwd = pwd;
}
}

发现上面代码既无hashCodeequalstoString也无set

加上data且把变量改为var,对应的java文件如下:

public final class UserBean {
@NotNull
private String id;
@NotNull
private String name;
@NotNull
private String pwd;

@NotNull
public final String getId() {
return this.id;
}

public final void setId(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, “<set-?>”);
this.id = var1;
}

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

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

@NotNull
public final String getPwd() {
return this.pwd;
}

public final void setPwd(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, “<set-?>”);
this.pwd = var1;
}

public UserBean(@NotNull String id, @NotNull String name, @NotNull String pwd) {
Intrinsics.checkNotNullParameter(id, “id”);
Intrinsics.checkNotNullParameter(name, “name”);
Intrinsics.checkNotNullParameter(pwd, “pwd”);
super();
this.id = id;
this.name = name;
this.pwd = pwd;
}

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

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

@NotNull
public final String component3() {
return this.pwd;
}

@NotNull
public final UserBean copy(@NotNull String id, @NotNull String name, @NotNull String pwd) {
Intrinsics.checkNotNullParameter(id, “id”);
Intrinsics.checkNotNullParameter(name, “name”);
Intrinsics.checkNotNullParameter(pwd, “pwd”);
return new UserBean(id, name, pwd);
}

// F F : s y n t h e t i c m e t h o d p u b l i c s t a t i c U s e r B e a n c o p y FF: synthetic method public static UserBean copy FF:syntheticmethodpublicstaticUserBeancopydefault(UserBean var0, String var1, String var2, String var3, int var4, Object var5) {
if ((var4 & 1) != 0) {
var1 = var0.id;
}

if ((var4 & 2) != 0) {
var2 = var0.name;
}

if ((var4 & 4) != 0) {
var3 = var0.pwd;
}

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

@NotNull
public String toString() {
return “UserBean(id=” + this.id + “, name=” + this.name + “, pwd=” + this.pwd + “)”;
}

public int hashCode() {
String var10000 = this.id;
int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;
String var10001 = this.name;
var1 = (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31;
var10001 = this.pwd;
return var1 + (var10001 != null ? var10001.hashCode() : 0);
}

public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof UserBean) {
UserBean var2 = (UserBean)var1;
if (Intrinsics.areEqual(this.id, var2.id) && Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.pwd, var2.pwd)) {
return true;
}
}

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

此时则和手动编写的java bean功能一样了,所有方法都可正常运行

单例类

目前Java使用最广的单例模式的实现如下:

public class Singleton {
private Singleton() {
}

private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
public void test() {

}
}

Kotlin中创建单例类需选择Object

生成代码如下:

object Singleton {
fun test() {

}
}

其对应的java文件如下,和上述使用最多的java单例实现类似

public final class Singleton {
@NotNull
public static final Singleton INSTANCE;

public final void test() {
}

private Singleton() {
}

static {
Singleton var0 = new Singleton();
INSTANCE = var0;
}
}

使用如下:

fun main() {
Singleton.test() //对应的java代码为Singleton.INSTANCE.test();
}

Lambda

许多高级语言都支持Lambdajavajdk1.8以后才支持Lamda语法,LamdaKotlin的灵魂所在,此小节对Lambda的基础进行学习,并借助集合练习。

集合的创建和遍历
List

fun main() {
//常规创建
val list = ArrayList()
list.add(1)
list.add(2)
list.add(3)

//listOf不可变,后续不可添加删除,只能查
val list1 = listOf(1, 2, 3 ,4 ,5)
list1.add(6)//报错

//mutableListOf,后续可添加删除
val list2 = mutableListOf(1, 2, 3 ,4 ,5)
list2.add(6)

//循环
for (value in list2) {
println(value)
}
}

Set

set用法与List类似,只是把listOf替换为mapOf

Map

fun main() {
val map = HashMap<String, String>()
map.put(“1”, “zjm”)
map.put(“2”, “ljn”)
//Kotlin中map支持类似下标的赋值和访问
map[“3”] = “lsb”
map[“4”] = “lyx”
println(map[“2”])
println(map.get(“1”))

//不可变
val map1 = mapOf<String, String>(“1” to “zjm”, “2” to “ljn”)
map1[“3”] = “lsb” //报错

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

ambda

许多高级语言都支持Lambdajavajdk1.8以后才支持Lamda语法,LamdaKotlin的灵魂所在,此小节对Lambda的基础进行学习,并借助集合练习。

集合的创建和遍历
List

fun main() {
//常规创建
val list = ArrayList()
list.add(1)
list.add(2)
list.add(3)

//listOf不可变,后续不可添加删除,只能查
val list1 = listOf(1, 2, 3 ,4 ,5)
list1.add(6)//报错

//mutableListOf,后续可添加删除
val list2 = mutableListOf(1, 2, 3 ,4 ,5)
list2.add(6)

//循环
for (value in list2) {
println(value)
}
}

Set

set用法与List类似,只是把listOf替换为mapOf

Map

fun main() {
val map = HashMap<String, String>()
map.put(“1”, “zjm”)
map.put(“2”, “ljn”)
//Kotlin中map支持类似下标的赋值和访问
map[“3”] = “lsb”
map[“4”] = “lyx”
println(map[“2”])
println(map.get(“1”))

//不可变
val map1 = mapOf<String, String>(“1” to “zjm”, “2” to “ljn”)
map1[“3”] = “lsb” //报错

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


[外链图片转存中…(img-Vr6vYSDN-1715894133835)]
[外链图片转存中…(img-Z7acDpTt-1715894133835)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值