Kotlin基础学习
kotlin基础学习笔记,便于以后查询
变量与常量的定义与赋值
/*
定义变量
var 变量名 = 值
var 变量名:变量类型 = 值
*/
var age1 = 18
var age2:Long = 20
var name = "张三"
var flag = true
/*
定义常量
val 常量名 = 值
val 常量名:常量类型 = 值
*/
val PI1 = 3.14
val PI2:Int = 3
/*
/*
数组定义
*/
var numbers1 = 1..100 //区间[1,100]
var numbers2 = 1 until 100 //区间[1,100)
//以二进制方式复制 0b代表二进制
var a:Int = 0b11
//获取Byte类型数据的取值范围
val byteMax = Byte.MAX_VALUE
val byteMin = Byte.MIN_VALUE
函数定义
/*
fun 方法名(参数1:参数1类型,参数2:参数2类型):返回值类型{
函数体
}
当返回值为空的时候可以不写,也可以写Unit
*/
fun add(a:Int,b:Int):Int{
return a+b
}
//常规函数定义
fun plus(a:Int,b:Int):Int{
return a+b
}
//简略函数定义
fun Add(a:Int,b:Int):Int = a+b
//方式3
var i = {a:Int,b:Int -> a+b}
//方式4
var j:(Int,Int) -> Int = {a,b -> a+b}
fun main(args: Array<String>) {
println(i(8,9))
println(plus(8,9))
println(Add(8,9))
println(j(8,9))
}
条件判断
//条件判断与其他语言使用方法一样,当只有一条执行语句时{}可以省略
fun ChooseBigValue(a:Int,b:Int):Int{
if(a>b)return a else return b
}
fun main(args: Array<String>) {
var a=12
var b=20
println("${a}和${b}之间最大的数是${ChooseBigValue(a,b)}")
}
空值处理
/*
当形式参数指定了参数类型之后,就不能传递null,
若想传递null可以在参数类型后面加?
*/
fun Welcome(name:String?):String{
return name+",你好!"
}
fun main(args: Array<String>) {
println(Welcome("张三"))
println(Welcome(null)) //如果未加?,此处报错
}
when表达式
/*
when表达式与switch表达式类似
*/
fun ScoreRank_A(score:Int):String{
var rank = when(score){
10 -> "优秀"
9 ->"漂亮"
8 ->"就很棒"
else ->"啥也不是"
}
return rank
}
fun ScoreRank_B(score:Int){
when(score){
10 -> println("优秀")
9 -> println("漂亮")
8 -> println("nice")
7 -> println("一般")
6 -> println("加油")
}
}
fun main(args: Array<String>) {
println("张三"+ScoreRank_A(10))
ScoreRank_B(8)
}
for循环
/*
数组定义
var 数组名 = a..b 代表[a,b]的数组
var 数组名 = a until b 代表[a,b)的数组
for循环
for(临时变量名 in 数组){}; 一步一步前进
for(临时变量名 in 数组 step 数字){} 设置步长,跳跃式前进
数组操作
数组名.reversed() 数组反转操作
数组名.count() 数组总长度
*/
var numbers1 = 1..100 //区间[1,100]
var numbers2 = 1 until 100 //区间[1,100)
fun main(args: Array<String>) {
for(num in numbers1){
print(" "+num)
}
println(" ");
for(num in numbers2){
print(" "+num)
}
println(" ");
for(num in numbers1 step 3){
print(" "+num)
}
println(" ");
var numbers3 = numbers1.reversed();
for(num in numbers3){
print(" "+num)
}
println("数组1的长度为"+numbers1.count())
}
List使用
fun main(args: Array<String>) {
var list = listOf("a","b","c","d")
//直接遍历
for(l in list){
println(l)
}
//带有索引遍历
for((i,j) in list.withIndex()){
println("$i $j")
}
}
Map使用
/*
Map使用:键值对 例{"11":"你好"}
*/
fun main(args: Array<String>) {
var map=TreeMap<String,String>();
map["1"] = "hello"
map["w"] = "world"
println(map["1"])
}
默认参数与具名参数
/*
默认参数与具名参数使用
当函数的一个形参是固定值时,此时可以只传递一个参数
*/
val PI = 3.1415926f
fun getArea(pi:Float = PI,R:Float):Float{
return pi*R*R
}
fun main(args: Array<String>) {
println("圆的面积为:"+getArea(R=4.0f))
}
字符串与数字转化
//字符串与数字相互转化
var x = "123"
var y = 123
var z = "a4"
fun main(args: Array<String>) {
println(x.toInt()+y)
println(x+y.toString())
// println(z.toInt()) 报错
}
键盘录入
/*
键盘录入的数据为字符串需要转为int才能进行操作,
但是若录入为空依然不能相加,!!表示非空
*/
fun main(args: Array<String>) {
println("请输入第一个数")
var x = readLine()
println("请输入第二个数")
var y = readLine()
println(x!!.toInt()+y!!.toInt())
}
异常处理
//与java异常处理一样
fun main(args: Array<String>) {
println("请输入第一个数")
var x = readLine()
println("请输入第二个数")
var y = readLine()
try{
println(x!!.toInt()+y!!.toInt())
}catch(e:Exception){
println("输入数据格式有误")
}
}
递归
//除下述之外,还可以进行尾递归优化,tailrec关键字
fun JC(a:Int):Int{
if(a==1)
return 1
else
return a*JC(a-1)
}
fun main(args: Array<String>) {
var n = 5
println(JC(n))
}
面向对象
class Student {
var name:String=""
var age:Int = 0
var sex = "男"
val PI = 3.14
fun smile(){
println("$name 笑了")
}
}
fun main(args: Array<String>) {
var st = Student() //创建对象不需要 new 关键字
st.name = "张三"
st.age = 18
println(st.name)
st.smile()
继承
何为继承:通俗点说,就是你可以用你爹的东西,如果不想用你爹的这个东西,你可以将其覆盖掉。若想某个类可被继承,则该类需要使用open关键字修饰,此时子类才可继承
(:父类名字())
;若想覆盖父类的某个方法,那么该方法需要使用open关键字修饰,此时子类方可重写该方法。
类属性修饰符
类属性修饰符 | 作用 |
---|---|
abstract | 抽象类 |
final | 最终类,不可更改 |
enum | 枚举类 |
open | 类可继承 |
annotation | 注解类 |
open class Father {
var word:String = "这个世界很美好"
open fun action(){
println("请你不要那么暴躁")
}
}
class Son :Father() {
override fun action() {
print("这是儿子自己的方法")
}
}
fun main() {
var s =Son();
println(s.word)
s.action()
}
抽象
抽象类和抽象方法必须使用abstract修饰,抽象类不可实例化,因为他不是具体的;
抽象类中可以有非抽象方法,但是有抽象方法必须是抽象类;
抽象类可以有构造方法,用于子类对父类进行初始化。
若子类不是抽象类,则需要继承父类的所有抽象方法
若子类是抽象类,则无需继承所有抽象方法
人类(anstract class)
男性(class Man)
女性(class Woman)
abstract class Human(var name:String) {
abstract fun eat() //只有方法名没有方法体
abstract fun cry()
}
class Woman(name:String):Human(name) {
override fun eat() {
println("男人吃饭")
}
override fun cry() {
println("女人哭泣")
}
}
class Man(name:String):Human(name) {
override fun eat() {
println("女人吃饭")
}
override fun cry() {
println("男人哭泣")
}
}
fun main() {
var man =Man("张三")
var woman = Woman("如花")
man.eat()
man.cry()
woman.eat()
woman.cry()
}
接口
接口是事物的能力
抽象类是事物的本质
一个类只能继承一个父类,但能实现多个接口
interface ImpleMan {
fun abilitity()
}
interface ImpleMan2 {
fun Study()
}
class Man(name:String):Human(name),ImpleMan,ImpleMan2 {
override fun eat() {
println("男人吃饭")
}
override fun cry() {
println("男人哭泣")
}
override fun abilitity() {
println("迪迦奥特曼变身")
}
override fun Study() {
println("男人正在学习")
}
}
fun main() {
var man =Man("张三")
man.eat()
man.cry()
man.Study()
man.abilitity()
}
fun main() {
var man =Man("张三")
var woman = Woman("如花")
var list = listOf<Human>(man,woman)
//遍历
for (l in list){
if (l is Man){
println("男人")
}
}
}
委托和代理
委托就是自己的事情委托别人去做
代理就是代理别人做事情
A,B继承了同一个接口,B中的动作可以通过by A()
语句交给A来做,此时不需要重写接口中的方法。
使用object代替class可以保证该类的对象有且只有一个
interface Iaction {
fun action()
}
class A :Iaction{
override fun action() {
println("A做事")
}
}
class B :Iaction by A() {
}
fun main() {
var a = A()
a.action()
var b = B()
b.action()
}
枚举类
enum class Direction {
UP,DOWN,LEFT,RIGHT
}
fun main() {
println(Direction.DOWN.ordinal)
}
密封类
密封类:子类类型有限的类
枚举类:更在意数据
sealed class Son{
class C():Son() //子类C
class D():Son() //子类D
fun sayHello(){
println("HELLO")
}
}
fun main() {
var s1 = Son.C()
var s2 = Son.D()
var s3 = Son.C()
var list = listOf<Son>(s1,s2,s3)
for ( l in list){
if(l is Son.C){
l.sayHello() //因为有两个C对象所以会打印两次
}
}
}
函数式编程
//n变量相当于一个函数,而foreach接收的是一个函数
//函数引用之后,不能写函数名
var n = fun (name:String){
println(name)
}
fun main() {
var person = listOf<String>("Tom","Jerry","lucy")
person.forEach(n)
}
fun main() {
var person = listOf<String>("Tom","Jerry","lucy")
person.forEach{
//匿名函数
a -> println(a)
}
}
//上述代码相当于
fun main() {
var person = listOf<String>("Tom","Jerry","lucy")
for(p in person){
println(p)
}
}
高阶函数
参数为函数的函数
或者返回值为函数的函数
以下几种为常用的高阶函数
//姓名 年龄 身高
data class Girl(var name:String,var age:Int,var height:Int)
var girllist = listOf<Girl>(
Girl("小黄",24,165),
Girl("小丽",12,168),
Girl("小红",19,173)
)
maxBy{it.对象属性}
minBy{it.对象属性}
fun main() {
println(girllist.maxBy{it.age}) // 获取年龄最大的女性
println(girllist.minBy{it.age}) //获取年龄最小的女性
}
filter{过滤条件}
fun main() {
//获取年龄大于18,身高在170以上的女孩
println(girllist.filter{
(it.age>18) and (it.height>170) //过滤条件
})
}
map{}函数
fun main() {
//将对象的某几个属性构建成新的集合
var map = girllist.map{
"${it.name}: ${it.age}"
}
println(map)
}
any{}函数
是否有满足条件的对象,返回值为Boolean类型
fun main() {
//是否有年龄为18岁的女孩
var g=girllist.any{
it.age == 18
}
print(g)
}
count{}函数
满足某个条件的对象有多少个
fun main() {
//是否有年龄为18岁的女孩
var n = girllist.count{
it.age>18
}
print(n)
}
find{}函数
查找第一个满足条件的对象并返回
fun main() {
//查询第一个年龄大于十八岁的女孩
var n = girllist.find{
it.age>18
}
print(n)
}
groupBy{}函数
按照对象属性,将对象分为不同的组
fun main() {
//将年龄为12岁的分为一个组,并打印出来
girllist.groupBy{
it.age
}.get(12)?.forEach { print(it) }
}
DSL(领域特定语言)
扩展函数
data class Girl(var name:String,var age:Int,var height:Int)
var girllist = listOf<Girl>(
Girl("小黄",24,165),
Girl("小丽",12,168),
Girl("小红",12,173)
)
//扩展函数
fun List<Girl>.查找女孩年龄小于(age: Int){
filter{
it.age<age
}.forEach ( ::println )
}
fun main() {
girllist.查找女孩年龄小于(18)
}
中缀表达式
上述需要使用
.
来调用还不是很方便,此时只需要在扩展函数前面加上infix就可以实现用空格来调用。如果这些名称全部使用汉语的话,程序就像说话一样,很方便。
//扩展函数
infix fun List<Girl>.查找女孩年龄小于(age: Int){
filter{
it.age<age
}.forEach ( ::println )
}
fun main() {
girllist 查找女孩年龄小于(18)
}