Kotlin 学习
Kotlin是一种解释型语言:解释型语言会逐行读取源代码,然后实时的将这些源代码解释成计算机可识别的二进制数据后再执行,通常效率会差一些。
优势:
- 语法更加简洁,相比java来说代码里大大减少
- 语法更加高级,采用了很多现代高级语言的语法特性,提高了开发效率
- 增加了语言安全性
- 与java是完全兼容的,可以直接调用java编写的代码,也可也无缝使用java第三方的开源库(原因:java和Kotlin编译后都生成一种特殊的class文件。再用java虚拟机识别,解释成为计算机可以识别的二进制数据后在执行)
变量
只有val和var
val(value):不可变变量
var(variable):可变变量
舍弃了单独定义int,string这种方式,使用类型推导机制(val a=10)确定变量类型Kotlin每行代码结尾不用写分号
若延迟赋值(val a)则不能确定类型,此时需要显示声明变量(val a:Int =10 )
在Kotlin中基本数据类型均变成了对象数据类型,首字母大写,拥有自己的方法和继承结构
- Note:能用val不用var,避免被错误修改,这样会更健壮
函数
实际上函数和方法是同一种概念,不同语言叫法不一样。
函数语法规则
fun methodName(param1:Int,param2:Int):Int{
return 0
}
- 参数的声明格式是:“参数名:参数类型”,如果不想接受任何参数,可以不用写,直接一个()就可以了
- 括号后边的那个“:Int”表示返回类型是Int,可以省略
- 使用代码补全功能,这样可以自动导包,否则全部手动敲会报错
例:
fun largerNumber(num1:Int,num2:Int):Int{
return max(num1,num2)
}
语法糖
如果一个函数只有一行代码,那么可以不用写函数体,直接用等号相连。除此之外,根据上面所说过的类型推导机制,max函数返回的是Int,故largerNumber返回值肯定也是Int,故返回值类型也可以省略。如下:
fun largerNumber(num1:Int,num2:Int):Int=max(num1,num2)
fun largerNumber(num1:Int,num2:Int)=max(num1,num2)
逻辑控制
if语句
与java基本相同,例:
if(a>b)
return a
else
return b
区别:if语句可以有返回值返回值是if语句每一个条件最后一行代码的返回值
val value=if(a>b){
a}
else{
b}
when语句
与switch类似,但更强大,
基本形式
fun getScore(name:String)=when(name){
"Tom"->88
"jim"->77
"jack"->99
else->0
}
格式:匹配值->{执行逻辑}
{}可以省略
除精准匹配外,还有类型匹配
fun checkStyle(num:Number){
when(num){
is Int->println("int")
is Double->println("double")
else ->println("no such style")
}
}
不带参数的when语句
fun getScore(name:String)=when{
name.startsWith("TOM")->86
name=="jim"->77
name=="jake"->99
else->0
}
ps:
- Int,Double,Float等与数字相关的都是Number的子类
- is关键字类似于java中的instanceof关键字
- Kotlin中判断是否相等可以直接使用“==”关键字,而不用像java中那样调用equals()方法
while循环
与java完全一样
for循环
java中的for-i循环被舍弃,for-each循环被加强变成了for-in循环
建立一个双端区间
val range=0..10
"…"是创建两端闭区间的关键字,上边的等价于[0,10]
升序
建立一个左闭右开的区间
val range=0 until 10
"until"关键字建立左闭右开区间
升序
建立一个降序区间
“downTo”
for-in循环
for(i in 0..10){
println(i)
}
for(i in 0 until 10 step 2){
println(i)
//[0,10),步长为2
}
for(i in 10 downTo 0){
println(i)
//降序
}
类和对象
在Android Stdio中,File通常用来编写Kotlin顶层函数和扩展函数的。
在Kotlin中也是使用关键字“class”来声明一个类,下面给出一个例子
class Person{
var name=""//使用var定义,是因为在初始化完成后在创建对象的时候还需要输入,ps:**这个和java中的私密性,声明为private好像不太一样**
var age=0
fun eat(){
println(name+"is eatting.He is "+age+"years old")
}
}
val p=Person()//实例化,此时声明为val,且不需要new关键字
p.name="jack"
p.age=19
p.eat()
继承与构造函数
再Kotlin中默认任何一个非抽象类(抽象类本身无法创建实例,必须要子类继承才可以创建实例)都是不可以继承的,相当于java中添加了final关键字(原因:如果一个类被允许继承的话,无法预知子类如何实现,会存在一些未知的风险)
实例:
open class Person{
...
}
class Student:Person(){//在java中继承关键字是extends,此处是冒号
var sno=""
var grade=0
}
上面Person类为什么要加一个()?
主构造函数
每个类都默认有一个不带参数的主构造函数,特点是没有函数体,直接定义在类名后边即可。例如
class Student(val sno:String,val grade:Int):Person(){
}//声明为val,是因为在构造实例的时候不需要重新赋值,因此可以声明成val
//如果想要编写一些逻辑,可以使用init结构体,例如
class Student(val sno:String,val grade:Int):Person(){
init{
println("sno is "+sno)
println("grade is "+grade)//逻辑
}
}//创建该类的实例化时,会进行打印
//实例化时
val student=Student("a123",5)
这里直接与字符串拼接就自动变成字符串了?
子类的构造函数进行实例化的时候必须调用父类的构造函数,在继承的时候通过()中的内容进行指定,上边那个空括号代表调用默认的无参数构造函数
下边是一个有参数的构造函数来进行一下讲解
//父类
open class Person(val name:String,val age:Int){
···
}
class Student(val sno:String,val grade:Int,name:String,age:Int):Person(name,age){
···
}//后边的name和age不声明val或者var是因为在Person中已经声明过了,再次声明会冲突
val student=Student("a132",4,"jack",10)
次构造函数
任何一个类只能有一个主构造函数,但可以有多个次构造函数。此构造函数可以用于实例化一个类,并且有函数体。
当既有主又有次时,次构造函数必须调用或者间接调用主构造函数
class Student(val sno:String,val grade:Int,name:String,age:Int):Person(name,age){
constructor(name:String,age:Int):this("",0,name,age){
}//次1,this调用了主,用于接受name和age参数,并且将son和grade赋初值
constructor():this("",0){
}//次2,this调用了次1,并将name和age赋初值
}
//实例化
val student1=Student("a123",1,"jack",10)//主
val student2=Student("jack",10)//次1
val student3=Student()//次2
不需要加()的特例
class Student:Person{
constructor(name:String,age:Int):super(name,age){
}
}
上边提到如果主次都有,那么次必须调用主。在刚才的例子中没有主,故继承Person类的时候就不需要加()了。只有次,故用super调用父构造函数。
接口
Kotlin和java均是但继承结构的语言,一个类最多继承一个父类,但可以实现多个接口
在接口中定义一系列抽象行为然后通过具体的类去实现
创建方法:创建类型选择Interface
interface Study{
fun readBooks()
fun doHomework(){
println("do homework")
}
}//接口中的函数一般没有函数体
//在类中使用
class Student(name:String,age:Int):Person(name,age),Study{
override fun readBooks(){
println(name+"is reading")
}
override fun doHomework(){
println(name+"is do homework")
}
}
在Kotlin中,继承和实现接口均用的冒号,中间用逗号隔开,上边表示Student继承于Person,实现了Study接口。接口后边不用加括号,因为没有构造函数去调用
重写父类或者接口函数的时候用关键字override
- 一般来说接口中的函数没有函数体
- 如果有了函数体,这就是默认实现
- 在继承接口后,没有函数体的函数要求必须实现,有函数体的可以不实现。
函数可见性修饰符、
Kotlin中有4中修饰符:
- public:表示对所有类都可见,是默认选项(java中default是默认选项)
- private:只对当前类内部可见
- protected:只对当前类和子类可见(java中表示对当前类、子类和同一包路径下的类可见)
- internal:只对同一模块中的类可见
数据类
数据类用于奖服务器端或数据库中的数据映射到内存中,为编程逻辑提供数据模型的支持。无论哪一种架构模式,其中的M指的就是数据类。
数据类通常要重写equals(),hashCode(),toString()这几个方法
。
toString()用来提供更清晰的输入日志,否则一个数据类默认打印出来的就是一行内存地址。
在Kotlin中不需要,只需要关键字“data”,Kotlin会根据主构造方法中的参数减少上述代码的生成。
data class Cellphone(val brand:String,val price:Double)
单例类
单例模式,用于避免构建重复的对象,比如希望全局最多只有一个实例。
在kotlin中只需要使用关键字“object”即可
创建方法:
Kotlin Files/Class->创建类型选择Object
//创建
object Singleton{
fun singletonTest(){
println("This is a single class")
}
}
//函数调用
Singleton.singletonTest()
本次介绍到此结束,主要是基础知识,进阶还需要继续学习
文章主要参考郭霖大佬所著的《第一行代码》