Kotlin的重新学习--06类型的进阶

构造函数

Java 代码块 和Kt的init块的区别

  • Java 构造函数代码块无法访问构造函数的参数
  • Kt的init块可以返回构造函数参数

属性必须被初始化

class Person(var age: Int, Name: String) {
  var name: String
    var firstname: String
    // 必须可空类型才能赋值null
    var firstname2: String?=null
    init {
        name=Name
        // 这里注释掉的话,firstname报错
      //  firstname = Name
    }

}

副构造器的使用

class Person(var age: Int, Name: String) {
    // 副必须调用主, 保证主必须被执行
    constructor(age:Int):this(age,"unknown")
}

使用注解@JvmOverloads,使得Java可以使用

class Person constructor(var age: Int, Name: String) : Animal() {

    // 副必须调用主
    @JvmOverloads
    constructor(age: Int) : this(age, "unknown")
}

构造函数的工厂函数,提供了对调用形式的便利

@kotlin.internal.InlineOnly
public actual inline fun String(chars: CharArray): String =
    java.lang.String(chars) as String

Java VS Kotlin 可见性对比

可见性类型 Java Kotlin
public 公开 默认
internal x 模块内可见
default 包内可见 x
protected 包内已经子类可见 类以及子类
private 类可见 类或者文件

模块的概念: 一个Java ,或者aar

internal vs default

  • 一般由SDK 或者公共组件开发者用于隐藏模块内部细节实现
  • default 可通过外部创建相同包名来访问
  • default 会导致不同抽象层次的类聚集到相同包之下
  • internal 可方便处理内外隔离,提升模块代码内聚减少接口暴露
  • internal 修饰的Kotlin 在java 当中可直接访问

假定一种情景,我制作一个SDK,我使用的类在内部调用,又不想被外部使用. Java之类防止在一个包名下面,并修改为 default--不分层.Kotlin 可以使用internal

有趣的是:kotlin编译的SDK,使用internal修饰的类,java的使用者可以直接访问,虽然代码会报错.这是因为,Java没有internal, 这个时候我们使用注解@JvmName("%abcd"),使用一个不正确的name就不能使用了

class CoreApiKotlinA {
    
    @JvmName("%abc")
    internal fun a(){
        println("Hello A")
    }
}

延时初始化lateinit,不支持基本类型

findViewByID的使用

方法1:
lateinit var view:View
view:View = findViewById(Id)

方法2:
private val View by lazy{
    findViewByID<View>(Id)
}


带来 delegate

接口代理--属性代理

接口代理: 对象x 代替当前类A实现接口B的方法
属性代理: 对象X 代替属性a 实现getter/setter方法

interface Api {
    fun a();
    fun b();
    fun c();
}

class ApiImp : Api {
    override fun a() {

    }

    override fun b() {

    }

    override fun c() {

    }
}

// 使用 `by 属性实例`,就能够完成代理
class ApiImpWrapper(val api: Api) : Api by api {
    override fun c() {
        println("c is called")
        api.c()
    }
}

属性代理

lazy

class Student(var name: String) {
    val firstName by lazy {
        "firstName ${name.split(" ")[1]}"
    }
}

fun main() {
    val stu = Student("li mei")
    println(stu.firstName)
    stu.name="xiao qiang"
    println(stu.firstName)
    
    // 两次打印是一样的,说明lazy 的值只会初始化一次
}

属性代理的案例

// by x, x 是方法,必须返回类, 类实现 getter 和setter

class PropertiesDelegate(
    private val path: String, private val defaultValue: String = "",
) {

    private lateinit var url: URL

    protected val properties: Properties by lazy {
        val prop = Properties()


        url = try {
            javaClass.getResourceAsStream(path)
                .use {
                    prop.load(it)
                }
            javaClass.getResource(path)
        } catch (e: Exception) {
            try {
                ClassLoader.getSystemClassLoader().getResourceAsStream(path).use {
                    prop.load(it)
                }
                ClassLoader.getSystemClassLoader().getResource(path)!!
            } catch (e: Exception) {
                FileInputStream(path).use {
                    prop.load(it)
                }
                URL("file://${File(path).canonicalPath}")
            }
        }
        prop
    }


    operator fun getValue(config: Config, property: KProperty<*>): String {
        return properties.getProperty(property.name, defaultValue)
    }

    operator fun setValue(config: Config, property: KProperty<*>, value: String) {
        properties.setProperty(property.name, value)

        File(url.toURI()).outputStream().use {
            properties.store(it, "Hello~")
        }
    }


}

abstract class AbsProperties(path: String) {
    protected val prop = PropertiesDelegate(path)
}

class Config : AbsProperties("Config.properties") {

    var author by prop
    var version by prop
    var desc by prop

}

class K {

    // by xxxx ,  xxxx 是函数的调用. 该调用必须返回类, 由类实现  getValue 和setValue的方法
    val x: Int by myLaze {
        1
    }

    private fun myLaze(function: () -> Int) = X(function)

}

class X(function: () -> Int) {
    operator fun getValue(k: K, property: KProperty<*>): Int {
        return 1
    }

}

单例

// 饿汉式的单例
object Singleton {

      // 其实x和y 已经是静态了

    var x: Int = 2


    @JvmStatic
    var y: Int = 3

    @JvmField
    var z :Int =4

}

   public static void main(String[] args) {

        int x = Singleton.INSTANCE.getX();

        int y = Singleton.getY();
      
          int z = Singleton.z;
    }

注: Kotlin没有静态的关键字

companion object 伴生对象

相当于静态方法

内部类

class Outer {

    //内部类: 默认是静态
    class Inner1 {

    }


    // 普通内部类,可以访问Outer
    inner class Inner2 {

    }

}


fun main() {
        
    // 静态
    val inner1 = Outer.Inner1()
    // 非静态
    val inner2 = Outer().Inner2()

}


内部object

就是单例/静态

匿名内部类/ 面试

fun main() {


    fun localFunc() {
        
        println("Hello")

        class local : Cloneable, Runnable {
            override fun run() {
                
            }
        }


// 交叉类型
        object : Outer(), Runnable, Cloneable {
            override fun run() {

            }
        }

    }


}

本地函数, 函数里面定义函数

数据类 data class

下列方法直接生成

  • 主构造器的参数,会变成 componentX
  • equals/hashCode/toString/copy
  • 数据类 data class 不能被继承
  • 最好是基本类型
  • 最好是val

插件

noarg.. dataClass 多一个无参构造方法,可配置init 的执行

allopen
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容