kotlin语法的基础学习和进阶学习

1基础的函数使用

1kotlin语言有具名函数参数,就是调用函数时不需要按照参数的顺序去填充参数,可以不按照参数声明顺序去调用

fun functionTest(name:String,age:Int){
    
    
    println("name=${
      
      name},age=$age")
    val num1=1000_000_000
    val num2=100
    println(num1+num2)
}

2kotlin语言的Unit返回类型可以省略,和java的区别是,void是关键字,而Unit是类
3kotlin中的反引号作用:将java中的普通名称但是在kotlin中又是关键字的函数名,加上单反引号后就可视为一个普通的名称

package com.njupt.base

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/07/10:33
 *@Description:
 */
fun main(){
    
    
    你是谁()
}
private fun `你是谁`(){
    
    
    println("我是你爹")
    YinhaoTest.`in`()
}

4匿名函数

package com.njupt.base

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/07/10:33
 *@Description:匿名函数的编写步骤
 */
fun main(){
    
    
    //第一步:声明函数的函数名输入和输出类型以及返回值类型等
    val function1 :()->String
    //第二步:编写函数的具体实现细节
    function1 ={
    
    
        var name:String="你是我的小艾小苹果"
        val length=name.count{
    
    
            it == '我'
        }
        //最后一行就是返回值,不需要写return语句
        name
    }
    //第三步:调用即可
    println(function1())

}

有参数的匿名函数的编写

package com.njupt.base

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/07/10:33
 *@Description:匿名函数的编写步骤
 */
fun main(){
    
    
    //第一步:声明函数的函数名输入和输出类型以及返回值类型等,编写函数的具体实现细节
    val function1 :(Int,String)->String={
    
    
        num1,num2 ->
        "返回的值为参数1:$num1,参数2:$num2"
    }


    //第三步:调用即可
    println(function1(1,"啊啊啊"))

}



5当函数只有一个参数时,可以隐式的获取参数名为it,见方法三

package com.njupt.base

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/07/10:33
 *@Description:匿名函数的编写步骤
 */
fun main(){
    
    
    //第一步:声明函数的函数名输入和输出类型以及返回值类型等,编写函数的具体实现细节
    val function1 :(Int,String)->String={
    
    
        num1,num2 ->
        "返回的值为参数1:$num1,参数2:$num2"
    }
    //第三步:调用即可
    println(function1(1,"啊啊啊"))

    val function2 :(String,Int)->String={
    
    
        name1,num2->
        "$name1,$num2"
    }
    println(function2("哈哈",12))

    //对于只有一个参数的函数,会有一个默认的参数it
    val function3:(Int) -> Int={
    
    
        it*it
    }
    println(function3(3))

}

6kotlin中匿名函数的写法

package com.njupt.base

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/07/16:55
 *@Description:
 */
fun main(){
    
    
    //自定义判断返回参数类型,不需要指定函数的返回值,这就是匿名函数
    val name={
    
    
        a:Int,b:Int,c:Int->
        val d=a*b
        d*c
    }
    
    val week = {
    
     a: Int ->
        //参数是Int类型,但是返回值是Any类型
        when (a) {
    
    
            1 -> "星期一"
            2 -> "星期2"
            3 -> "星期3"
            4 -> "星期4"
            else -> -1
        }
    }
    println(week(-1))
    println(name(2,2,2))
}

7函数作为另一个函数的参数的使用
7.1java的写法

package com.njupt.base;

/**
 * Creat with IntelliJ IDEA
 *
 * @Auther:倔强的加瓦
 * @Date:2022/10/07/10:37
 * @Description:
 */
interface ResultJson{
    
    
    void code(String mess,int code);
}
public class YinhaoTest {
    
    
    public static void main(String[] args) {
    
    
        login("123", "123", new ResultJson() {
    
    
            @Override
            public void code(String mess, int code) {
    
    
                System.out.println("信息是:"+mess+":状态码是:"+code);
            }
        });
    }
    public static void login(String name,String psw,ResultJson resultJson){
    
    
        if(name.equals("abc")&&psw.equals("123")){
    
    
            resultJson.code("登录成功",200);
        }else{
    
    
            resultJson.code("登录失败",444);
        }
    }
}

7.2.使用kotlin的写法,可以省略接口的写法。

package com.njupt.base

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/07/16:55
 *@Description:
 */
fun main() {
    
    
    //虽然有三个参数,但是第三个参数是函数,需要写在外面
    login("abc","123"){
    
    
        mess:String,code:Int->
        println("信息是:$mess,状态码是:$code")
    }


}

//登录密码的验证,从而返回响应包,将函数作为第三个参数
fun login(name:String,pwd:String,responseCode:(String,Int)->Unit){
    
    
    if(name=="abc"&&pwd=="123"){
    
    
        responseCode("登录成功",200)
    }else{
    
    
        responseCode("登录失败",444)
    }
}

内联函数的引入:在当函数作为另一个函数的参数时,从字节码的角度看就是要创建对象去调用作为参数的方法,但是引入内敛函数后可以避免创建对象相互调用带来的消耗

情况1,不引入内敛函数上面代码反编译的情况:

package com.njupt.base;

import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {
    
    1, 1, 18},
   bv = {
    
    1, 0, 3},
   k = 2,
   d1 = {
    
    "\u0000\u001c\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\u0010\b\n\u0002\b\u0002\u001a0\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u00032\u0018\u0010\u0005\u001a\u0014\u0012\u0004\u0012\u00020\u0003\u0012\u0004\u0012\u00020\u0007\u0012\u0004\u0012\u00020\u00010\u0006\u001a\u0006\u0010\b\u001a\u00020\u0001¨\u0006\t"},
   d2 = {
    
    "login", "", "name", "", "pwd", "responseCode", "Lkotlin/Function2;", "", "main", "kotlin_base"}
)
public final class SoutTest2Kt {
    
    
   public static final void main() {
    
    
      login("abc", "123", (Function2)null.INSTANCE);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
    
    
      main();
   }

   public static final void login(@NotNull String name, @NotNull String pwd, @NotNull Function2 responseCode) {
    
    
      Intrinsics.checkParameterIsNotNull(name, "name");
      Intrinsics.checkParameterIsNotNull(pwd, "pwd");
      Intrinsics.checkParameterIsNotNull(responseCode, "responseCode");
      if (Intrinsics.areEqual(name, "abc") && Intrinsics.areEqual(pwd, "123")) {
    
    
         responseCode.invoke("登录成功", 200);
      } else {
    
    
         responseCode.invoke("登录失败", 444);
      }

   }
}

情况2引入内联函数的情况

package com.njupt.base;

import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {
    
    1, 1, 18},
   bv = {
    
    1, 0, 3},
   k = 2,
   d1 = {
    
    "\u0000\u001c\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\u0010\b\n\u0002\b\u0002\u001a3\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u00032\u0018\u0010\u0005\u001a\u0014\u0012\u0004\u0012\u00020\u0003\u0012\u0004\u0012\u00020\u0007\u0012\u0004\u0012\u00020\u00010\u0006H\u0086\b\u001a\u0006\u0010\b\u001a\u00020\u0001¨\u0006\t"},
   d2 = {
    
    "login", "", "name", "", "pwd", "responseCode", "Lkotlin/Function2;", "", "main", "kotlin_base"}
)
public final class SoutTest2Kt {
    
    
   public static final void main() {
    
    
      String name$iv = "abc";
      String pwd$iv = "123";
      int $i$f$login = false;
      short code;
      String mess;
      boolean var5;
      String var6;
      boolean var7;
      if (Intrinsics.areEqual(name$iv, "abc") && Intrinsics.areEqual(pwd$iv, "123")) {
    
    
         code = 200;
         mess = "登录成功";
         var5 = false;
         var6 = "信息是:" + mess + ",状态码是:" + code;
         var7 = false;
         System.out.println(var6);
      } else {
    
    
         code = 444;
         mess = "登录失败";
         var5 = false;
         var6 = "信息是:" + mess + ",状态码是:" + code;
         var7 = false;
         System.out.println(var6);
      }

   }

   // $FF: synthetic method
   public static void main(String[] var0) {
    
    
      main();
   }

   public static final void login(@NotNull String name, @NotNull String pwd, @NotNull Function2 responseCode) {
    
    
      int $i$f$login = 0;
      Intrinsics.checkParameterIsNotNull(name, "name");
      Intrinsics.checkParameterIsNotNull(pwd, "pwd");
      Intrinsics.checkParameterIsNotNull(responseCode, "responseCode");
      if (Intrinsics.areEqual(name, "abc") && Intrinsics.areEqual(pwd, "123")) {
    
    
         responseCode.invoke("登录成功", 200);
      } else {
    
    
         responseCode.invoke("登录失败", 444);
      }

   }
}

2let apply also run 内置函数的使用

1.let的学习

//let函数的特点:
//1调用者在方法体内有一个代替者it
//当需要返回值时,大括号的最后一行就是返回值,并且不需要写return语句

package com.njupt.second

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/09/15:26
 *@Description:
 */
fun main() {
    
    
    //let函数的特点:
    //1调用者在方法体内有一个代替者it
    //当需要返回值时,大括号的最后一行就是返回值,并且不需要写return语句
    //例如
    println(checkNull(null))
    println(checkNull2(null))
    var name="1231231231"
    name.let {
    
    
        it.length>5
    }.let {
    
    
        if(it) "长度大于5" else "长度小于5"
    }.let {
    
    
        "$it"
    }.let(::print)

}
//常规的判空
fun checkNull(name:String?):String{
    
    
    if(name==null){
    
    
        return "你在搞什么飞机,姓名不能为null"
    }else{
    
    
        return "欢迎你$name!"
    }
}
//使用let函数进行判空
fun checkNull2(name :String?):String{
    
    
    return name?.let{
    
    
        "欢迎你$it"
    } ?: "你在搞什么飞机,姓名不能为null"
}

2.apply

//apply内置函数的特点:
//1谁调用返回值就是谁
//2相比于let的单参数时it,apply的是this,可以隐藏
//3可以链式的调用

package com.njupt.second

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/09/15:04
 *@Description:
 *
 */
fun main() {
    
    
    //apply内置函数的特点:
    //1谁调用返回值就是谁
    //2相比于let的单参数时it,apply的是this,可以隐藏
    //3可以链式的调用
    var str:String="Abcd Efg Hijk"
    //调用的返回值类型就是调用者
    var strNew=str.apply {
    
    
        //使用this对象代替
        println(this.toUpperCase())
    }.apply {
    
    
        //使用this对象代替
        println(this.length)
    }.apply {
    
    
        //省略this的调用者
        println(indexOf('A'))
    }

    println(strNew)
}

3,run

//run内置函数的特点
//1最后一行就是返回值
//2使用this来表示调用的结果,返回结果是什么类型,下一次调用this时就是什么类型
//3可以链式的调用具名函数和匿名函数

package com.njupt.second

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/09/16:51
 *@Description:
 */
fun main() {
    
    
    //run内置函数的特点
    //1最后一行就是返回值
    //2使用this来表示调用的结果,返回结果是什么类型,下一次调用this时就是什么类型
    //3可以链式的调用具名函数和匿名函数
    var name:String="asddasda"
    //1使用匿名函数进行链式调用
    var result=name.run{
    
    
        this.length>5
        //第一次调用,this表示String类型,返回的是boolean类型
    }.run {
    
    
        //第二次调用this表示的是上次一返回的boolean类型,返回的是String类型
        if(this) "字符串大于5合格" else "不合格"
    }.run {
    
    
        //当前this是字符串类型,返回的也是字符串类型
        "[$this]"
    }
    println(result)

    //2使用具名函数进行调用
    name
        .run(::isLength)
        .run(::isLegal)
        .run (::println )



}
fun isLength(name:String):Boolean{
    
    
    return name.length>5
}
fun isLegal(length:Boolean):String{
    
    
   return if(length) "长度大于5" else "长度不合法"
}

4also方法

//also的特点:
//1谁调用also,返回值就是谁,元对象是不会变的,==apply
//2使用it来代替调用元素

package com.njupt.second

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/09/18:02
 *@Description:
 */
fun main() {
    
    
    //also的特点:
    //1谁调用also,返回值就是谁,元对象是不会变的,==apply
    //2使用it来代替调用元素
    var name:String = "aedwsas"
    var newStr=name.also{
    
    
        println(it.length)
    }.also {
    
    
        println(it)
    }
    println(newStr)
}

四种内置函数的总结。
在这里插入图片描述

最后一行就是返回值 谁调用就返回谁
it let also
this run apply

3可变集合和不可变集合的学习

1Array数组的使用

package com.njupt.third

import java.io.File

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/10/20:23
 *@Description:
 */
fun main() {
    
    
    var arr:IntArray = intArrayOf(1,2,3,4,2)
    println(arr[0])
    //遍历
    arr.forEach {
    
     println(it)}

    //注意这个空返回值只能返回Int类型的数
    println(arr.elementAtOrElse(10) {
    
    -1})
    println(arr.elementAtOrNull(20) ?:"越界啦")

    //将数组转成集合
    val charArray= listOf('A','B','C').toCharArray()
    println(charArray)
    //还有一个针对存储对象的数组
    var objArray= arrayOf(File("路径1"),File("路径2"),File("路径3"))
}

2List链表的使用

package com.njupt.third

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/09/20:54
 *@Description:
 */
fun main() {
    
    
    //不可变的list集合
    var list= listOf<Int>(1,2,3,4)
    println(list.getOrNull(4) ?: "你越界了哈!")

    //将一个不可变的集合变成一个可变的集合
    var list3=list.toMutableList()

    //可变的list集合
    var listM= mutableListOf<Int>(1,2,3,4,5,6)
    listM.add(8)
    listM.remove(2)
    for(i in listM){
    
    
        println(i)
    }
    println(listM)

    //将可变的集合变成一个不可变的集合
    var list4=listM.toList()

    
}

3Set集合的使用

package com.njupt.third

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/10/19:48
 *@Description:
 */
fun main() {
    
    
    //set集合
    var set:Set<String> = setOf("as","abandon","if")
    //可变的set集合
    var mutableSet:Set<String> = mutableSetOf("as","sasd","asda","as")
    mutableSet+="asdaasda"
    //处理可能的越界问题
    println(set.elementAt(0))
    println(set.elementAtOrElse(11){
    
    "越界"})
    println(set.elementAtOrNull(10) ?: "越界")
    //将list集合变成一个set集合
    var list = mutableListOf<String>("1","1","2","3","4","4")
    //变成一个不可重复的set
    var listToSet=list.toSet()
    println(listToSet)
    //在变回来list
    var result:MutableList<String> =listToSet.toMutableList()
    println(result)

}

4map集合

package com.njupt.third

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/10/20:46
 *@Description:
 */
fun main() {
    
    
    //两种方式来定义
    var map:Map<String,String> = mapOf("a" to "a","b" to "b")
    var map1= mapOf(Pair("a","a"), Pair("b","b"))

    //三种方式来进行获取
    println(map["a"])
    //如果没有当前key,会返回 null
    println(map["c"])
    println(map.getOrDefault("b","不存在当前key"))
    println(map.getOrElse("a"){
    
    "不存在当前"})

    //三种方式来进行遍历
    //println(map)
    map.forEach{
    
    
        println(it.key+it.value)
    }

    map.forEach{
    
    
        key,value->
        println(key+value)
    }

    for(i in map){
    
    
        println(i.key+i.value)
    }

    //可变map集合的添加和删除
    val muMap:MutableMap<Int,Int> = mutableMapOf(Pair(1,1), Pair(2,2), Pair(3,3))
    muMap += 4 to 4
    muMap -= 1
    muMap.forEach {
    
    
        println("${
      
      it.key}+${
      
      it.value}")
    }
    muMap.put(5,5)
    //返回值,如果key存在就返回,如果不存在则插入并返回
    var r =muMap.getOrPut(6){
    
    6}
}

3kotlin中类字段field属性的使用

1省略set方法和get方法的field关键字的使用,以及对于空对象的防范竞态处理

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/23/12:39
 *@Description:关于field关键字的使用
 */

class FieldString{
    
    
    var name="小河"
        //这个就是java中的set和get方法
    get()=field
    set(value){
    
    
        field=value
    }

    /*get方法
     public  String getName(){
       return this.name;
     }
    */
    /*
    set方法
    public void setName(String value){
        this.name=value
    }
     */

    var letter="dc"
        //重载这个get方法
    get()=field.toUpperCase()
    set(value){
    
    
        //控制返回的结果格式
        field = value
    }

    //使用val代表不可变,其中不可变的解决方案就是没有set方法

    val age=18

    //在一些可空的对象,需要对其进行判空处理,叫做防范竞态条件
    val psw:String ? =null
    
    fun getShowPsw():String{
    
    
        return psw?.let{
    
    
            if(it.isEmpty()){
    
    
                "当前值为空字符串"
            }else{
    
    
                "$it"
            }
        } ?:"当前返回值为null"
    }

}
fun main() {
    
    

    var fieldString=FieldString()

    println(fieldString.name)
    fieldString.name="asdasd啊实打实的"
    println(fieldString.name)

    println(fieldString.letter)
    fieldString.letter="asdasd"
    println(fieldString.letter)

    //针对val修饰的变量只能进行获取,不能修改
    println(fieldString.age)
    
    //测试防范竞态条件,就是需要对可空的值进行可空处理
    println(fieldString.getShowPsw())
}

4Kotlin中的面向对象学习

1主构造方法和次构造方法的使用

package com.njupt.fourth

import com.njupt.base.add

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/23/17:15
 *@Description:
 */
//变量和主次构造函数的学习


//主构造方法和次构造方法,其中次构造方法一定要调用主构造方法,用于主构造统一管理,可以更好的初始化
class Teacher(name:String){
    
    
		//init初始代码块,当主构造方法执行时,一定会执行这个代码块里的内容,一般用来进行初始化和判空处理
    init{
    
    
        //注意require方法是判断如果为空则会怎么样,反着来的!如果为false则通过异常的方式结束程序
        require(name.isNotEmpty()){
    
    
            "你的name初始化的值为空"
        }
    }

    constructor(name:String,age:Int):this(name){
    
    
        println("使用第一个构造方法")
    }
    constructor(name:String,age:Int,address:String):this(name){
    
    
        println("使用了第二个构造方法")
    }

}

fun main(){
    
    
    var teacher=Teacher("张")
    Teacher("zjamh",18)
    Teacher("sda",12,"安徽省")
}

2主构造方法,此构造方法,初始化方法吗,属性赋值的执行顺序

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/23/20:00
 *@Description:
 */
//1先执行val age:Int
class People(_name:String,val age:Int){
    
    
    //2在生成name
    val name=_name
    //3执行初始化方法
    init{
    
    
        var nameInit=_name
        println("执行初始化方法")
    }
    //5调用次构造方法
    constructor(name:String,age: Int,address:String):this(name,age){
    
    
        println("次构造方法执行")
    }
    //4再次执行类的属性赋值
    val lang="asdas"
    
}

fun main() {
    
    
    //当执行次构造方法时执行顺序
    var people=People("hai",12,"安徽")
    
}

3懒加载机制

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/23/20:14
 *@Description:
 */
//lateinit var 和by Lazy的使用

//1 lateinit var是指定属性可以在先不进行初始化,只需要在使用时在进行初始化即可
//2by lazy是通过懒加载的方式实现调用

class LateInitTest{
    
    
    //在使用时是手动去加载,还有一种是自动惰性的加载即by lazy
    lateinit var name:String
    fun initName(){
    
    
        name="爱说大话"
    }
    fun useName(){
    
    
        println(name)
    }
    
    //当初始化时就会执行方法进行初始化,还没用到就进行了查询数据库操作
    //var result=readDatabase()
    //使用自动的方式去加载,懒汉模式,用到时才会去进行调用方法
    val result2 by lazy {
    
     readDatabase() }
    fun readDatabase():String{
    
    
        println("连接数据库")
        println("查询数据库")
        println("处理查询结果集")
        println("返回结果")
        return "数据库返回的结果是!!!!!"
    }
}

fun main(){
    
    

    //主线程中去调用,此时会初始化里面的变量,就会执行赋值的方法
    var iniLazy=LateInitTest()
    //主线程睡眠5秒
    Thread.sleep(5000)

    println(iniLazy.result2)
}

4open关键字
在kotlin中,所有的方法和类如果不加修饰,都是默认为final的,也就是不能被继承和重写,使用open关键字可以解决继承和重写的问题。

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/24/11:39
 *@Description:
 */

open class Country{
    
    
    //私有方法不能被重写
    private fun getPlace(){
    
    
        println("我是父类,中国!")
    }
    open fun getName(){
    
    
        println("我是父类的方法")
    }
}
class Province: Country() {
    
    
    
    override fun getName() {
    
    
        println("我是子类重写的方法")
    }
}
fun main() {
    
    
    //父类的引用指向子类的对象
    var p:Country=Province()
    p.getName()
}

5is 和 as关键字来判断对象的类型,然后进行处理,并且有一个只能类型,就是只要转过类型一次,下面都是已经进行转行的。

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/24/11:39
 *@Description:
 */

open class Country{
    
    
    //私有方法不能被重写
    fun getPlace(){
    
    
        println("我是父类,中国!")
    }
    open fun getName(){
    
    
        println("我是父类的方法")
    }
}
class Province: Country() {
    
    

    override fun getName() {
    
    
        println("我是子类重写的方法")
    }
    fun getPlace1(){
    
    
        println("我是子类,省")
    }
}
fun main() {
    
    
    //父类的引用指向子类的对象
    var p:Country=Province()
    p.getName()
    //使用is 进行强转,然后调用父类的方法
    if(p is Country){
    
    
        p as Country
        p.getPlace()
    }
    p.getPlace()

}

6kotlin中的超类Any,类似于java中的Object,在其中只有标准,没有具体的实现类,目的是为了进行跨平台,不同的平台实现类不同
7Kotlin中单例类的实现方式:使用Object 代替class去修饰类即可成为一个单例的类。

8kotlin中的匿名对象

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/24/11:53
 *@Description:
 */
open class NominusObject{
    
    
    open fun method1()= println("方法1")
    open fun method2()=print("方法2")
}
//使用匿名函数去调用和实现两个方法
fun main() {
    
    
    //使用匿名对象去重写方法
    var no=object :NominusObject(){
    
    
        override fun method1()=println("子类方法匿名对象去实现和调用了那个方法")
        override fun method2() {
    
    
            println("匿名对象去重写方法")
        }
    }
    no.method1()
    no.method2()
    //等价于使用具名对象去调用
    var sun=Sun()
    sun.method1()
    sun.method2()

    //3还可以使用匿名对象去实现接口中的方法
    var t1=object :Runnable{
    
    
        override fun run() {
    
    
            println("run方法执行。。。。。")
        }
    }
    t1.run()
}
//使用不匿名的方式就是
class Sun:NominusObject(){
    
    
    override fun method1()=println("子类方法具名对象去实现和调用了那个方法")
    override fun method2() {
    
    
        println("具名对象去重写方法")
    }
}

9伴生对象类,就是companion object,类似于java中的static静态类

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/24/12:31
 *@Description:
 */
class Student{
    
    
    companion object{
    
    
        var name="小光"
        fun getAge():Int{
    
    
            return 18
        }
    }
}
fun main() {
    
    
    //对于半生类可以使用类名直接调用
    println(Student.name)
    println(Student.getAge())
}

10内部类inner
当类进行嵌套时,外部类可以访问内部类,但是内部类不能访问外部类信息,外部类想要读取内部类吗,内部类想要获取外部类的信息,需要使用inner 关键字来修饰内部类。

package com.njupt.fourth

/**
 *Creat with IntelliJ IDEA
 *@Auther:倔强的加瓦
 *@Date:2022/10/24/12:31
 *@Description:
 */
class Student{
    
    
    var name1="夏普"
    companion object{
    
    
        var name="小光"
        fun getAge():Int{
    
    
            return 18
        }
    }

    
    inner class head{
    
    
        var qiguan="头部"
        //内部类去访问外部类
        fun getName()=println(name1)
    }

    fun getQiguan(){
    
    
        //外部类去访问内部类
        println(head().qiguan)
    }
}
fun main() {
    
    
    //对于半生类可以使用类名直接调用
    println(Student.name)
    println(Student.getAge())

    var student=Student()
    student.head().getName()
    student.getQiguan()
}

猜你喜欢

转载自blog.csdn.net/m0_56184347/article/details/127191464