Kotlin中的变量定义有2个关键字,val
和var
val用来定义不可变变量,第一次赋值后就不能再被修改了, var定义可变变量, 随便修改。一个好的编程习惯是, 能用val的就不要用var, 原因是安全, 这也是Kotlin中强制让你指明变量是否可变的原因。
针对变量定义, Kotlin有一个非常重要的机制, 类型自动推导, 那意味着可以告别C/C++, Java, 等语言中非常繁琐的变量定义方法。
上几个例子感受一下这种变量定义的简洁之处吧。
Kotlin定义方式:
val name = 'leo'
var age = 18
python定义方式:
name = 'leo'
age = 18
java定义方式:
string name = 'leo';
int age = 18;
简洁性方面, 高下立判。 python yyds! Kotlin也还不错。 但这里不是为了比较不同编程语言, 仅仅是为 了对比加深印象。
上面的例子中, Kotlin就省略了类型定义, 其实是有编译器自动帮我们推导的。类型自动推导可以满足大多数的要求, 但有些场景类型是无法自动推导出来的,比如延迟赋值等场景, 这个时候还是需要手动指明变量类型的。如果需要手动指明的话, 方法是在变量名后加: 变量类型
, 如:
val name : String = 'leo'
var age : Int = 18
写法上还是比较自然的。
编程中经常会有函数和方法两个术语, 其实两者完全一样, 没有任何区别, 习惯叫法不同而已。
函数就是一堆代码的集合,为了方便, 把多条代码封装在一起。
直接上个例子,对例子讲解吧:
fun myFunc(name: String, age: Int) : Int{
return 0
}
要点如下:
fun
(function的缩写)myFunc
是函数名, 建议起名遵循命名规范以及见名知意的原则变量名:变量类型
的格式书写, 没有入参可以空着不写:Int
定义了返回值类型, 同样的, 没有返回值也可以省略python写法:
def myFunc(name, age):
return 0
java写法:
public static int myFunc(string name, int age){
return 0;
}
fun getScore(score: Int){
if (score>80){
print("Very good")
}
else if (score>60) {
print("Good")
}
else {
print("Bad")
}
}
上面是常规的 if else 语句,比较简单直观,应该不会过多讲解。
when语句相当于其他编程语言中的swith case 语句, 但是更加简洁和强大。
fun getScore(score: Int){
when(score) {
80-> print("Very Good")
60-> print("Good")
else -> print("Bad")
}
}
语法要点是, 在when中传入一个任意类型的参数, when的结构体中定义一系列的条件, 格式是:
匹配值 -> {执行逻辑}
。 当执行逻辑只有一句时, 可以省略{}。 也就得到了上面代码的写法。
注意上面用when语句写的代码功能与上面用if else写的不一样。因为when接收的是一个参数, 而上面if else 中的条件是一个表达式。 那这时候就可以用无参数的when表达式了。
fun getScore(score: Int){
when {
score>80 -> print("Very Good")
score>60 -> print("Good")
else -> print("Bad")
}
}
注意代码的变化, 因为无参数传入,when后面的括号不需要了, 表达式的计算放在when的结构体里面。 这个代码的功能就跟上面的if else定义的完全一致了。
var index =5
while (index>0) {
println(index)
index --
}
输出 5 4 3 2 1
var index =5
do {
prinltn(index)
index --
}
while (index>0)
}
输出 5 4 3 2 1
Kotlin的for in 循环与python非常类似, 基本语法是for (变量 in 可迭代对象)
, 可迭代对象包括数组, 列表等等。
for (index in 1..10)
println(index)
上面的1…10是一个区间, 它是一个可迭代的对象。 ..
是创建两端闭区间的关键字。 也就是说, 上面的区间是包含1和10的。 通常我们用的左闭右开区间多一些, 这个时候用until
, 1 until 10
, 就是1到9,不包括10。 还能通过step
控制步长, downTo
可以实现降序, 10 downTo 1
就是从10 到1.
for (index in 1..10 step 2)
println(index)
类是面向对象编程中最重要的概念了。
先上个示例:
class Person() {
val name = "leo"
val age = 18
fun getInfo() {
print("name is: $name , age is: $age.")
}
}
fun main() {
val person = Person()
person.getInfo()
}
类的定义用关键字class
, Person
是类名, 括号中可以填入构造方法的参数,如果没有参数可以为空, 但是括号不能省。 {}中的是类的实现, 类中可以定义变量和函数。 在 val person = Person() 这句话是实例化一个对象。
上面是最简单的类的定义方法。 其实是跟python比较相似的, 甚至比python还要简洁一些。 为了加深印象, 看下python是怎么写的:
class Person():
def __init__():
self.name = "leo"
self.age = 18
def getInfo():
print(f"name is {self.name}, age is {self.age}.")
if __name__ = __main__:
person = Person()
person.getInfo()
上面代码中的__init__
是python的构造函数,可以带参数,也可以不带参数, 上面的定义中就是不带参数的。 Kotlin中也有init构造函数,而且跟python非常类似。
说几点主要不同:
__init__
中。最简单的继承语法是: class 类名():被继承的父类()
如我们定义一个Student类继承上面的Person类。
class Student(): Person(){
fun getInfoNew() {
getInfo()
}
}
fun main() {
val student = Student()
student.getInfoNew()
}
输出
name is: leo , age is: 18.
上面的例子中可以清晰地体现继承, 继承可以继承到父类的变量和方法。
注意Kotlin的类默认不能继承, 要想能被继承, 需要用open关键字修饰
上面的类都是不带构造参数的, 但是通常我们定义的类都是带构造参数的。 带构造参数的类定义稍微复杂一些, 如下:
open class Person(val name: String, val age: Int) {
fun getInfo() {
print("name is: $name , age is: $age.")
}
}
class Student(val sex: String, name: String, age:Int): Person(name, age){
fun getInfoNew() {
getInfo()
}
}
fun main() {
val student = Student("man", "leo",18)
student.getInfoNew()
}
带参数的类定义有以下几点需要注意:
数据类算是一种特殊的类, 与一般的类相比,需要实现equals()、hashCode()、toString()这几个方法。
数据类一般都是用来定义各种数据的, 用一个类来实现方便管理。
这几个方法的实现实际上固定的模式。 所以Kotlin中已经帮我们实现好了, 只需要简单地加个data关键字就可以了。
data class myData(val brand:String, val price :Int)
fun main() {
var mydata = myData("Apple", 5999)
var mydata1 = myData("Huawei", 4999)
println(mydata)
println("mydata equal to mydata1: ${mydata==mydata1}")
}
输出:
myData(brand=Apple, price=5999)
mydata equal to mydata1: false
注意上面的 == 判断调用的就是equals() 方法。
单例类也是一种特殊的类, 单例类的对象在全局只能存在一个。 在Kotlin中定义单例类非常简单, 把class关键字换成object就可以了。
object Singleton {
fun func1(){
println("this is singleton")
}
}
fun main() {
Singleton.func1()
}
单例类没有构造函数,因此Singleton后面不带()。
调用单例类的方法跟其他语言中调用静态方法一样, 直接用类名调用, 不需要实例化(实际上, 因为没有构造函数, 也没法实例化)。
;