(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~
Kotlin语言基础学习
Kotlin体系文档
文章目录
1.为什么学习Kotlin?
(1)Google规定的官方Android语言。
(2)侵权,侵java的权
(3)jetbrains与google在主推
2.Kotlin基础语法
2.1Var 与 Val
(1)可变变量定义:var 关键字
var <标识符> : <类型> = <初始化值>
(2)不可变变量定义:val 关键字,只能赋值一次的变量(有一点点类似Java中final修饰的变量)
val <标识符> : <类型> = <初始化值>
/**
* 1.var 与 val
* 1.1可变变量定义:var 关键字
* var <标识符> : <类型> = <初始化值>
*
* 1.2不可变变量定义:val 关键字,只能赋值一次的变量(有一点点类似Java中final修饰的变量)
* val <标识符> : <类型> = <初始化值>
*/
fun main(){
//1.var用于定义变量,可以修改的
var name:String = "中国"
//1.1赋值
name = "李连杰"
name = "成龙"
//2.val用于定义不可以修改的值
val age:Int = 99
}
class Test{
var info1 : String = "A"
val info2 : String = "B"
}
(3)一个Kotlin文件本质上是一个java文件,例如以上Test类实际上是如下java类。
(4)选中文件,tools–>Kotlin—>Show Kotlin Bytecode
package com.gdc.kotlin.sample01.s01;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 1,
d1 = {"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0007\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002R\u001a\u0010\u0003\u001a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\"\u0004\b\u0007\u0010\bR\u0014\u0010\t\u001a\u00020\u0004X\u0086D¢\u0006\b\n\u0000\u001a\u0004\b\n\u0010\u0006¨\u0006\u000b"},
d2 = {"Lcom/gdc/kotlin/sample01/s01/Test;", "", "()V", "info1", "", "getInfo1", "()Ljava/lang/String;", "setInfo1", "(Ljava/lang/String;)V", "info2", "getInfo2", "kotlin"}
)
public final class Test {
@NotNull
private String info1 = "A";
@NotNull
private final String info2 = "B";
@NotNull
public final String getInfo1() {
return this.info1;
}
public final void setInfo1(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
this.info1 = var1;
}
@NotNull
public final String getInfo2() {
return this.info2;
}
}
(5)类型推倒
fun fun1(){
//1.类型推倒,用后面的类型推倒变量的类型
var info1 = "AAAA"
//1.1类型推倒: Char
var info2 :Char = 'A' //全写
var info21 = 'A'//审略写法
//1.2类型推倒:Int
var info3 :Int = 33
}
(6)Kotlin是静态语言
fun fun2(){
//1.Kotlin是静态语言
//1.1编译期 就决定了 String类型
val info1 = "LISI"
//info1 = 88
}
2.2函数
/**
* 1.函数
* 1.1Kotlin返回值 Unit即为main函数的返回值,类似于java的void
*/
fun main() : Unit{
println(add(1,1))
//1.1.1检测可变参数
add4(1,2,3,4,5);
//1.1.2lambda表达式函数
//val lambda:函数名
//:(Int,Int):参数类型
//->Int:函数返回值类型
//->{number1,number2 -> number1 + number2}:函数参数名与函数返回值
val addMethod : (Int,Int) -> Int ={number1,number2 -> number1 + number2}
//1.1.3lambda函数调用
val r = addMethod(102,22)
println(r)
}
/**
* 1.2Kotlin带参数返回值的函数
*/
fun add(number1:Int,number2:Int) : Int{
return number1 + number2;
}
/**
* 1.3函数返回类型=类型推倒 Int
*/
fun add2(number1:Int,number2: Int) = number1 + number2
/**
* 1.4类型推倒 String
*/
fun add3(number1:Int,number2: Int) = "AAA"
/**
* 1.5可变函数参数
*/
fun add4(vararg value :Int){
for(i in value){
println(i)
}
}
2.3字符串模版
/**
* 1.字符串模板
* 1.1 $ 表示一个变量名或者变量值
* 1.2 $varName 表示变量值
* 1.3 ${varName.fun()} 表示变量的方法返回值
*/
fun fun1(){
val name = "张三"
val age = 28
val sex = 'M'
val info = "ABCDEFG"
println("name:$name,age:$age,sex:$sex,info:$info")
}
/**
* 2.不用关心/n换行的问题
* 2.1如果不使用trimIndent()函数,就会存在前置空格
*/
fun fun2(){
//2.2没有空格
val infoMessage1 = """
AAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEE
""".trimIndent()
println(infoMessage1)
//2.3有空格
val infoMessage2 = """
AAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEE
"""
println(infoMessage2)
//2.4输出没有空格通过|控制
val infoMessage3 = """
|AAAAAAAAAAAAAAAAAAAAA
|BBBBBBBBBBBBBBBBBBBBB
|CCCCCCCCCCCCCCCCCCCCC
|DDDDDDDDDDDDDDDDDDDDD
|EEEEEEEEEEEEEEEEEEEEE
""".trimMargin("|")
println(infoMessage3)
val infoMessage4 = """
?AAAAAAAAAAAAAAAAAAAAA
?BBBBBBBBBBBBBBBBBBBBB
?CCCCCCCCCCCCCCCCCCCCC
?DDDDDDDDDDDDDDDDDDDDD
?EEEEEEEEEEEEEEEEEEEEE
""".trimMargin("?")
println(infoMessage4)
}
2.3.1特殊符号打印
/**
* 3.需求:显示$9999.99
*/
fun fun3() : Unit{
val price = """
${'$'}9999.99
""".trimIndent()
println(price)
}
2.4空检查机制
/**
* 1.NULL检查机制
* 1.1Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,
*
* 1.2有两种处理方式:
* 1.2.1字段后加!!像Java一样抛出空异常
* 1.2.2另一种字段后加?
*/
fun main(){
//1.全体注意这个info可能null,使用的话,必须给出补救方案
var info : String? = null;
//1.1报错的原因:
//1.1.1第一种补救措施:使用?,如果info是null,就不执行.length,就不会引发空指针异常
println(info?.length)
//1.1.2第二种补救措施:使用!!,自己负责info不会为null,会引发KotlinNullPointerException空指针异常
println(info!!.length)
//1.1.3第三种,先判断后输出,与Java一样的做法
if(null != info){
print(info.length)
}
}
/**
* 2.默认返回null,如何做?
* 2.1Int?允许批回值为null
*/
fun testMethod(name : String) : Int?{
if(name == "ZhangSan"){
return 9999
}
return null;
}
使用三元运算符 ?:
/**
* 3.?: 如果你一定要输出null,就返回,三元运算符
* 3.1如果info为null就输出“你很牛逼”
*/
fun fun3(){
var info : String? = null;
println(info?.length ?: "你很牛逼");
}
2.5区间
fun main(){
//fun1();
//fun2()
//fun3()
//fun4()
//fun5()
fun6()
}
/**
* 1.区间
*/
fun fun1(){
//1到9
for(i in 1..9){
println(i)
}
}
/**
* 2.不会打印这样的区间
*/
fun fun2(){
for(i in 9..1){
println(i)
}
}
/**
* 3.从大到小输出
*/
fun fun3(){
for(i in 9 downTo 1){
println(i)
}
}
/**
* 4.用区间做判断
*/
fun fun4(){
val value = 88;
if(value in 1.. 100){
println("包含了1到100")
}
}
/**
* 5.跳步执行
* 5.1步长指定为5
*/
fun fun5(){
for(i in 1..20 step 5){
println(i)
}
}
/**
* 6.指定排除
* 6.1排除最后元素
*/
fun fun6(){
for(i in 1 until 10){
println(i)
}
}
3.Kotlin比较与数组
3.1比较两个值
/**
* 1.比较两个值
* 1.1比较值本身
*/
fun fun1() {
val name1: String = "李连杰"
val name2: String = "李连杰"
//1.1.1比较值本身
//1.1.2==等价Java.equal
println(name1.equals(name2))
println(name1 == name2)
}
/**
* 1.2比较对象地址
* 1.2.1返回false
*/
fun fun2(){
val test1:Int? = 1000
val test2:Int? = 1000
println(test1 === test2)
}
3.2数组
/**
* 1.数组
* 1.1第一种形式
*/
fun fun1(){
//1.1.1使用泛型限定数组元素类型
var numbers1 = arrayOf<Int>(1,2,3,4,5,6,7)
println(numbers1[0])
println(numbers1[6])
for (number in numbers1){
println(number)
}
//1.1.2不指定数组元素类型
var numbers2 = arrayOf(1,2,3,4,5,6,7)
}
/**
* 1.2第二种形式
*/
fun fun2(){
//1.2.1 20表示数组长度
//1.2.2 {value : Int -> (value + 100)}value默认从0开始跌代,跌代20次,
// 数组元素的值是当前跌代的值每次+1之后再加100的值。
//1.2.3 value : Int表示定义的一个变量类型
var numbers2 = Array(20,{value : Int -> (value + 100)})
for (number in numbers2) {
println(number)
}
}
4.Kotlin条件控制
/**
* 1.条件判断
* 1.1表达式比大小
*/
fun fun1(){
val number1 : Int = 9999;
val number2 : Int = 8888;
val maxValue = if(number1 > number2) number1 else number2
println(maxValue)
}
/**
* 1.1
*/
fun fun2(){
val number1 : Int = 9999;
val number2 : Int = 8888;
val max : Int = if(number1 > number2) {
println("number1是最大值")
//TODO
// .....
//返回值
number1
}else{
print("number2是最大值")
//TODO
// .....
//返回值
number2
}
println(max)
}
/**
* 1.3使用区间判断
*/
fun fun3(){
val x = 80
val y = 33
if(x in 1..10 && y in 1..50){
println("x在1-10区间范围,y在1到50区间范围")
}else{
println("xy不在区间范围内")
}
}
/**
* 1.4switch语句
*/
fun fun4(){
val number = 6;
when(number){
1 -> println("一")
2 -> println("二")
3 -> println("三")
4 -> println("四")
5 -> println("五")
else -> println("没有匹配的条件")
}
}
/**
* 1.5switch语句高级写法
*/
fun fun5(){
val number = 27;
when(number){
in 1..100 -> println("1..100")
in 200..500 -> println("200..500")
else -> println("没有匹配的条件")
}
}
/**
* 1.6switch when语句
*/
fun fun6(){
val number = 3
val result = when(number){
1->{
println("很开心")
//其他业务逻辑
//...
//TODO...
"今天是星期一"
}
2->{
println("很开心")
//其他业务逻辑
//...
//TODO...
"今天是星期二"
}
3->{
println("很开心")
//其他业务逻辑
//...
//TODO...
"今天是星期三"
}
else ->{
"其他"
}
}
println(result)
}
5.Kotlin循环与标签
/**
* 1.循环与标签
* 1.1把内层循环break掉
* 1.2通过自定义标签(aaaa@)结束外层循环
*/
fun fun1(){
aaaa@ for(i in 1..20){
for(j in 1..20){
println("i:$i,j:$j")
if(i == 5){
//1.把内层循环break掉
//break;
//2.通过标签结束外层循环
break@aaaa
}
}
}
}
/**
* 1.2.自带的标签
*/
class Derry{
val i = "AAAA"
fun show(){
println(i)
println(this.i)
println(this@Derry.i)
}
}
/**
* 1.3for循环
*/
fun fun2(){
var items = listOf<String>("张三","李四","李丽华")
for(item in items){
println(item)
}
}
/**
* 1.4 forEach
*/
fun fun3(){
var items = listOf<String>("张三","李四","李丽华")
items.forEach{
println(it)
}
}
/**
* 1.5amboda表达式
*/
fun fun4(){
var items = listOf<String>("张三","李四","李丽华")
items.forEach{
xx->
println(xx)
}
}
/**
* 1.6跌代器
*/
fun fun5(){
var items = listOf<String>("张三","李四","李丽华")
for(index in items.indices){
println("下标:$index,对应的值:${items[index]}")
}
}
6.Kotlin类与对象
6.1空类
/**
* 1.空类
* 1.1默认就是public
*/
class EmptyClass
6.2构造函数
fun main(){
//1.调用Person无参构造函数,即次构造3
val person1 = Person()
//2.调用Person类主构造函数
val person2 = Person(54)
//3.调用Person类次构造函数1
val person3 = Person(55,"张化")
//4.调用Person类次构造函数2
val person4 = Person(56,'M')
}
/**
* 1.主构造
* Person(id:Int)
* 1.1次构造必须要引用主构造,否则报错
* 1.2构造函数可以重载
*/
open class Person(id:Int){
/**
* 1.1次构造1
*/
constructor(id:Int,name:String) : this(id){
}
/**
* 1.2次构造2
*/
constructor(id:Int,name:Char) : this(id){
}
/**
* 1.3次构造3
*/
constructor() : this(88){
}
}
6.3继承
/**
* 1.继承
* 1.1使用":"实现继承
* 1.2调用次构造Person()
* 1.3调用主构造Person(id),子类构造id传给父类构造id
*/
class Student(id:Int) : Person(id){
//1.4在Kotlin中,所有的成员属性都没有默认值。
//1.4.1在Java中,所有的成员属性有默认值,但是在方法内部没有默认值
//1.4.2使用lateinit关键字实现懒加载,即使用的时候再初始化成员属性声明需要使用var关键字,确保可以修改
//1.4.3如果成员变量没有赋值,就不能使用,否则报错
lateinit var name : String
var age : Int = 0
}
6.4抽象类与接口
6.4.1接口
/**
* 接口默认都是open,即可以被子类实现
*/
interface Callback {
fun callbackMethod() : Boolean
}
interface Callback2 {
fun callbackMethod1() : Boolean
}
6.4.2抽象类
/**
* 1.类
* 1.1默认是 public final class Person,不能被子类继承
*/
/*class Person{
}*/
/**
* 2.类实现接口
*/
/*class Person : Callback{
override fun callbackMethod(): Boolean {
TODO("Not yet implemented")
}
}*/
/**
* 3.类实现接口并声明为抽象类
* 3.1声明为抽象类在类前加abstract关键字
* 3.2abstract有open的特征,相当于open
* 3.3声明抽象函数
*/
abstract class Person : Callback,Callback2{
//3.3.1抽象函数
abstract fun getLayoutId() : Int
//3.3.2抽象函数
abstract fun initView()
}
6.4.3子类实现抽象类与接口中的抽象函数
/**
* 1.子类实现抽象类及接口中的抽象方法
*/
class Student : Person(){
override fun getLayoutId(): Int = 256
override fun initView() {}
override fun callbackMethod(): Boolean = false
override fun callbackMethod1(): Boolean = true
}
6.5数据类(Java实体bean)
/**
* 1.数据类==Java实体类
* 1.1自动生成get set toString copy eqqals及其他方法
*/
data class User(var id:Int,var name:String,var sex : Char)
/**
* 1.使用数据类
*/
fun main(){
//1.1使用数据类
val user = User(99,"张化",'M')
println(user)
//1.2复制对象
val(myId,myName,mySex) = user.copy()
println("myId:$myId,myName:$myName,mySex:$mySex")
//1.3拒收克隆数据
val(_,myName1,mySex1) = user.copy()
println("myName:$myName1,mySex:$mySex1")
}
6.6创建类对象调用函数
/**
* 1.如果使用class关键字声明MyEngine时,其有默认构造
* 2.如果使用object关键字声明MyEngine时,表示其没有默认构造,可以用类名直接点函数名调用
* 2.1使用object关键字声明时,相当于只实例化一次,类似于Java单例模式
*/
object MyEngine{
fun m(){
println("M run")
}
}
/**
* 1.创建对象调用方法
* 1.1创建5个对象,实例化5次
* 1.2直接通过类名调用
*/
fun fun2(){
//1.2.1声明MyEngine时需要使用class关键字
/*MyEngine().m()
MyEngine().m()
MyEngine().m()
MyEngine().m()
MyEngine().m()*/
//1.2.2声明MyEngine时需要使用object关键字
MyEngine.m()
}
6.7单例模式
/**
* 1.Kotlin单例模式
*/
class NetManager {
object Holder{
val instance = NetManager()
}
//1.1看不到static关键字,可以使用派生操作
companion object{
//1.1.1在派生类中定义的变量,全部都是相当于Java中的static
//1.1.2简写方式
//fun getInstance() : NetManager = Holder.instance
fun getInstance() : NetManager{
return Holder.instance
}
}
fun show(name:String){
println("show:$name")
}
}
fun main(){
val net = NetManager.getInstance()
net.show("张三丰")
}
/**
* 单例模式2
*/
class NetManager2 {
companion object{
private var instance : NetManager2? = null
fun getInstance() : NetManager2{
if(null == instance){
instance = NetManager2()
}
//1.第二种补救措施,任何成员属性都应该赋初值,!!表示我来负责赋值,确保不为null
return instance!!
}
/**
* 允许返回null值,由调用处做补救措施
*/
fun getInstance1() : NetManager2?{
if(null == instance){
instance = NetManager2();
}
return instance;
}
}
fun show(name : String){
println("show:$name")
}
}
fun main(){
//1.方法返回值允许为null,由调用片来做补救措施
val netManager = NetManager2.getInstance1()
//1.1如果netManager为null,不执行show方法
netManager?.show("AAA")
}
6.8内部类
/**
* 1.内部类
*/
class Test {
val I = "AAAA"
/**
* 1.1这个不是一个内部类,所以拿不到外部类的成员变量
* 1.2可以在类的里面再写一个类,但是这个类和外部类不交换
*/
/*class Sub{
fun show(){
println(I)
}
}*/
/**
* 这个才是一个内部类
*/
inner class InnerSub{
fun show(){
println(I)
}
}
}
7.打赏鼓励
感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!