package com.mcc.myapplication
fungetNum(): Number {return100F}/**
* is 与 !is 操作符
*/funisDemo(){val obj ="hello"if(obj is String){println("string length:${obj.length}")}val value =1if(value is Int){println("$value is Int")}val num =getNum()if(num !is Int){println("$num not is Int")}}/**
* 智能转换
*/funtransferDemo(x: Any){if(x is String){println("this param is string, and length:${x.length}")// x 自动转换为字符串}}funtransferDemo2(x: Any){if(x !is String)return// 如果反向检测导致返回那么该转换是安全的println("this param is string, and length:${x.length}")}funtransferDemo3(x: Any){// `||` 右侧的 x 自动转换为 Stringif(x !is String || x.length ==0)return// `&&` 右侧的 x 自动转换为 Stringif(x is String && x.length >0){println("this param is string, and length:${x.length}")}}funtransferDemo4(x: Any){when(x){is Int ->print(x +1)is String ->print(x.length +1)is IntArray ->print(x.sum())}}funtransferDemo5(x: Any){// “不安全的”转换操作符val y: String?= x as String?if(y !=null){println("this param is string, and length:${x.length}")}}funtransferDemo6(x: Any){// “安全的”(可空)转换操作符val y: String?= x as? String
if(y !=null){println("this param is string, and length:${x.length}")}}funmain(){isDemo()transferDemo("world")transferDemo2("gogogo")transferDemo3("pythonX")transferDemo4(intArrayOf(1,2,3,4,5))transferDemo4(arrayOf(1,2,3,4,5,6))// transferDemo5(111)transferDemo6(111)}
If 表达式
funmain(){val a =2val b =3var max: Int?=nullif(a > b){
max = a
}else{
max = b
}// 作为表达式
max =if(a > b) a else b
println("max is $max")val c =10val maxOrLimit =if(c > a) c elseif(a > b) a else b
println("maxOrLimit is $maxOrLimit")// if 表达式的分支可以是代码块,这种情况最后的表达式作为该块的值val max2 =if(a > b){print("Choose a,")
a
}else{print("Choose b,")
b
}println("max2 is $max2")}
When 表达式
funwhenDemo1(x: Int){when(x){1->print("x == 1")2->print("x == 2")else->{print("x=$x is neither 1 nor 2")}}println()}enumclass Bit {
ZERO, ONE, TWO
}fungetRandomBit(): Bit {return Bit.ZERO
}funwhenDemo2(){val numericValue =when(getRandomBit()){
Bit.ZERO ->0
Bit.ONE ->1
Bit.TWO ->2// 'else' is not required because all cases are covered}println(numericValue)}funwhenDemo3(x: Int, s: String){when(x){0,1->print("x == 0 or x == 1")else->print("otherwise")}when(x){
s.toInt()->print("s encodes x")else->print("s does not encode x")}val validNumbers =listOf(3,4,5)when(x){in1..10->print("x is in the range")in validNumbers ->print("x is valid")!in10..20->print("x is outside the range")else->print("none of the above")}}funmain(){whenDemo1(3)whenDemo2()}
For 循环
funmain(){// for 循环可以对任何提供迭代器(iterator)的对象进行遍历val ints =listOf(2,3,4,5,6)for(item: Int in ints){print(item)}println()for(i in1..3){print(i)}println()for(i in6 downTo 0 step 2){print(i)}println()val array =arrayOf("a","b","c")for(i in array.indices){print(array[i])}println()for((index, value)in array.withIndex()){println("the element at $index is $value")}}
while 循环
while(x >0){
x--}do{val y =retrieveData()}while(y !=null)// y 在此处可见
返回与跳转
/**
* 在 Kotlin 中任何表达式都可以用标签来标记。 标签的格式为标识符后跟 @ 符号
*/fundemo1(){loop@for(i in1..100){for(j in1..100){if(j >1)break@loopprintln(j)}}}/**
* 返回到标签
*/fundemo2(){listOf(1,2,3,4,5).forEach{if(it ==3)return// 非局部直接返回到 demo2() 的调用者print(it)}println("this point is unreachable")}fundemo3(){listOf(1,2,3,4,5).forEach lit@{if(it ==3)return@lit// 局部返回到该 lambda 表达式的调用者——forEach 循环print(it)}print(" done with explicit label")}fundemo4(){listOf(1,2,3,4,5).forEach{if(it ==3)return@forEach// 局部返回到该 lambda 表达式的调用者——forEach 循环print(it)}print(" done with implicit label")}fundemo5(){listOf(1,2,3,4,5).forEach(fun(value: Int){if(value ==3)return// 局部返回到匿名函数的调用者——forEach 循环print(value)})print(" done with anonymous function")}funmain(){demo5()}
package com.mcc.myapplication
import javax.inject.Inject
class Person {/*……*/}class Empty
class Student constructor(firstName: String){/*……*/}// 如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字// class Student(firstName: String) { /*……*/ }class Customer public@Injectconstructor(name: String){/*……*/}// 如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的classInitOrderDemo(name: String){val firstProperty ="First property: $name".also(::println)init{println("First initializer block that prints $name")}val secondProperty ="Second property: ${name.length}".also(::println)init{println("Second initializer block that prints ${name.length}")}}classPerson2(val firstName: String,val lastName: String,var age: Int)classPerson3(val firstName: String,val lastName: String,var isEmployed: Boolean =true)// 次构造函数classPerson4(val pets: MutableList<Pet>=mutableListOf())class Pet {constructor(owner: Person4){
owner.pets.add(this)// adds this pet to the list of its owner's pets}}classPerson5(val name: String){val children: MutableList<Person5>=mutableListOf()// 如果类有一个主构造函数,每个次构造函数需要委托给主构造函数,// 可以直接委托或者通过别的次构造函数间接委托// 委托到同一个类的另一个构造函数用 this 关键字即可constructor(name: String, parent: Person5):this(name){
parent.children.add(this)}}class Constructors {init{println("Init block")}constructor(i: Int){println("Constructor i=$i")}constructor(i: Int, ss: String):this(i){println("Constructor ss=$ss")}}// 如果一个非抽象类没有声明任何(主或次)构造函数,它会有一个生成的不带参数的主构造函数。构造函数的可见性是 public。class DoCreateMe privateconstructor(){/*……*/}// 如果你不希望你的类有一个公有构造函数,那么声明一个带有非默认可见性的空的主构造函数class DonotCreateMe privateconstructor(){/*……*/}// 如果主构造函数的所有的参数都有默认值,编译器会生成一个额外的无参构造函数classCustomer2(val name: String ="",val age: Int =18)funmain(){val p =Person()val e =Empty()val s =Student("SnZ")InitOrderDemo("YourName")Person2("morning","cat",30)Person3("morning","cat")val p4 =Person4()Pet(p4)Pet(p4)
p4.pets.toList().joinToString().also(::println)val p5 =Person5("ZhangSan")Person5("ZhangXiao", p5)Constructors(33,"mcc")Customer2()}
抽象类
// 类以及其中的某些或全部成员可以声明为 abstractabstractclass Polygon {abstractfundraw()}class Rectangle :Polygon(){overridefundraw(){// draw the rectangle}}// 可以用一个抽象成员覆盖一个非抽象的开放成员openclass Polygon2 {openfundraw(){// some default polygon drawing method}}abstractclass WildShape :Polygon2(){// Classes that inherit WildShape need to provide their own// draw method instead of using the default on Polygonabstractoverridefundraw()}
类的继承
package com.mcc.myapplication
// 在 Kotlin 中所有类都有一个共同的超类 Any,对于没有超类型声明的类它是默认超类class Example :Any()// 从 Any 隐式继承// 默认情况下,Kotlin 类是最终(final)的——它们不能被继承。 要使一个类可继承,请用 open 关键字openclassBase(p: Int)// 该类开放继承classDerived(p: Int):Base(p)// 如果派生类没有主构造函数,那么每个次构造函数必须使用super 关键字初始化其基类型class MyClass : Base {constructor(ctx: Int):super(ctx)constructor(ctx: Int, name: String):super(ctx)}// Kotlin 对于可覆盖的成员以及覆盖后的成员需要显式修饰符openclass Shape {openval vertexCount: Int =0openfundraw(){/*……*/}// 如果函数没有标注 open 如 Shape.fill(),那么子类中不允许定义相同签名的函数funfill(){/*……*/}}classCircle():Shape(){overridefundraw(){/*……*/}}// 将 open 修饰符添加到 final 类(即没有 open 的类) 的成员上不起作用// 标记为 override 的成员本身是开放的,因此可以在子类中覆盖。如果你想禁止再次覆盖, 使用 final 关键字openclassRectangle():Shape(){// 属性与方法的覆盖机制相同。在超类中声明然后在派生类中重新声明的属性必须以 override 开头,并且它们必须具有兼容的类型。overrideval vertexCount =4finaloverridefundraw(){/*……*/}}interface Shape2 {val vertexCount: Int
}classRectangle2(overrideval vertexCount: Int =4): Shape2 // 总是有 4 个顶点class Polygon2 : Shape2 {overridevar vertexCount: Int =0// 以后可以设置为任何数}// 派生类初始化顺序// 调用超类实现// 覆盖规则funmain(){}