美文网首页
二、类型初步

二、类型初步

作者: 南小夕 | 来源:发表于2020-06-30 10:39 被阅读0次

    一. 类和接口

    1. 类的定义
      默认为 public 可省略,类内无内容可省略{}
    class SimpleClass {
      var x : Int = 0 // 必须初始化
      constructor(x : Int){ // 构造函数
        this.x = x
      }
    }
    

    可以简化为:

    class SimpleClass ( var x : Int ){
    
    }
    
    1. 类的实例化
      可以省掉new
    val simpleClass = SimpleClass(9)
    println(simpleClass.x)
    simpleClass.y()
    
    1. 接口的定义
      和Java没有什么区别
    interface SimpleInf {
      fun simpleMethod()
    }
    

    接口的实现

    class SimpleClass(var x : Int) : SimpleInf {
      ...
      override fun simpleMethod(){
      }
    }
    
    1. 抽象类的定义
      和Java没什么区别
    abstract class AbsClass {
      abstract fun absMethod()
      open fun overridable(){}
      fun nonOverridable(){}
    }
    

    需要注意:kotlin 中它所有的类默认都是 final 的,那么就意味着不能被继承,而且在类中所有的方法也默认是 final 的,不能被重写,如果想要继承或重写,只需要在类或方法前添加 open 关键字即可。

    1. 属性引用
    val ageRef = Person::age // 未绑定receiver
    val person = Person(18,"Jone")// 绑定receiver
    val nameRef = person.name
    ageRef.set(person,20)
    nameRef.set("Andy")
    

    二. 扩展方法

    1. 定义
      直接新建一个 File 类型的 kt 文件,不是 class 类型,不是 interface 类型,不是枚举类型,不是 Object 类型,仅仅是 File 类型。
      可以定义扩展方法、扩展属性。
    // 类型可以省略,即任意类型
    fun 类型.方法名(参数...):返回值
    
    // 任意类型都可以调用
    fun add(a: Int, b: Int): Int{
        return a + b
    }
    
    //只能 String 类型可以调用
    fun String.times(count: Int): String{
      ...
    }
    

    调用:

    val a = 1
    val b = 2
    add(a, b)
    
    val result: String
    result.times(5)
    

    三. 空类型安全

    1. 可空类型
      !! 强制转换为不空类型
      ?. 安全调用成员
      ?: 前面的表达式为null 则执行后面的表达式
    var nullable: String? = "Hello"
    
    val length = nullable!!.length // !! 强制转成不空类型,如果你确定不可能为空,不然还是会空指针
    //或
    val length = nullable?.length ?:0 // elvis 安全访问
    
    1. 空类型的继承关系
      可空类型为不可空类型的父类
    var x: String = "Hello"
    var y: String? = "World"
    
    // x = y ,不可以
    // y = x,可以
    

    四. 智能类型转换

    A as B 类型转换
    A as? B 安全转换,失败返回 null

    public interface Kotliner{}
    
    public class Person implements Kotliner{
      public final String name;
      public final int age;
    
      public Person(String name, int age) {
        this.name = name;
        this.age = age;
      }
    }
    

    转换:

    val kotliner: Kotliner = Person("benny", 20)
    if(kotliner is Person) {
      //println((kotliner as Person).name) // kotliner 自动转换类型为Person
     println((kotliner as? Person)?.name) // 安全转换
    }
    

    五. 建议

    1. 尽可能使用 val 来声明不可变引用,让程序的含义更加清晰确定;
    2. 尽可能减少函数对外部变量的访问,也为函数式编程提供基础;
    3. 必要时创建局部变量指向外部变量,避免因它变化引起程序错误;

    六. 案例

    使用 Retrofit 发网络请求

    1. 首先定义一个返回的数据结构
    data class Repository (
    var id: Int,
    var node_id: String,
    var name: String,
    var url: String
    )
    
    1. 定义一个接口
    interface GithubApi {
      @GET("/repos/{owner}/{repo}")
      fun getRepository(@Path("owner") owner: String, @Path("repo") repo: String): Call< Repository >  
    }
    
    1. 使用
    val gitHubApi = Retrofit.Build()
      .baseUrl("https://api.github.com")
      .addConverterFactory(GsonConverterFactory.create())
      .build()
      .create(GithubApi::class.java)
    
    val response = gitHubApi. getRepository("JetBrains","Kotlin").execute()
    
    val repository = response.body()
    
    if (repository == null) {
      println("Error!${response.code()}-${response.message()}")
    } else {
      println(repository.name)
    }
    

    相关文章

      网友评论

          本文标题:二、类型初步

          本文链接:https://www.haomeiwen.com/subject/itrhfktx.html