Kotlin嵌套类与内部类

Kotlin嵌套类与内部类

嵌套类

嵌套类就是类中的类,类可以嵌套在其他类中,可以嵌套多层。
访问嵌套类(Nested Class)的方式是直接使用“类名.”,有多少层嵌套,就用多少层类名加点号来访问。
嵌套类没有持有外部类的引用,所以是无法访问外部类的变量。

内部类

类可以标记为 inner 以便能够访问外部类的成员,这样的类叫内部类(Inner Class)。内部类会持有一个对外部类的对象的引用。

嵌套类、内部类的构造和使用

下面例子展示了Button类的 嵌套类内部类,以及 匿名内部类 的构造和使用。

import java.io.Serializable

interface State : Serializable

interface View {
    fun getCurrentState(): State
    fun restoreState(state: State) {}
}

interface OnClickListener {
    fun onClick(v: View?)
}

class Button : View {

    override fun getCurrentState(): State = ButtonState()
    private var mPrivateFlags: Int = 1
    var mListener: OnClickListener? = null

    override fun restoreState(state: State) {
        super.restoreState(state)
    }

    /**
     * 此类没有显示修饰符,称为嵌套类。
     * 嵌套类与Java中的static嵌套类是一样的
     * 不会存储(持有)外部类的引用
     */
    class ButtonState : State {} //对应Java中的static class ButtonState

    /**
     * 此类有inner修饰符,称为内部类
     * 内部类与Java中的非static内部类是一样的
     * 会存储(持有)外部类的引用
     */
    inner class ButtonState2 : State { //对应Java中的class ButtonState2
        /**
         * 在内部类中获取外部类的实例
         */
        fun getOuterReference(): Button = this@Button

        fun accessOutter() {
            println("accessOuter flag=$mPrivateFlags")
        }
    }

    fun setOnClickListener() {
        /**
         * 关于匿名内部类(Annonymous Inner Class):
         * 匿名内部类就是没有名字的内部类。既然是内部类,那么它自然也可以访问外部类的变量。
         */
        mListener = object : OnClickListener {
            override fun onClick(v: View?) {
                println("onClick mPrivateFlags=$mPrivateFlags")
            }
        }
    }
}

fun main(args: Array<String>) {
    //嵌套类不需要构造外部类对象
    val state = Button.ButtonState()

    //内部类要先构造外部类对象
    val state2 = Button().ButtonState2()
    state2.accessOutter() //accessOuter flag=1

    val btn = Button()
    btn.setOnClickListener()
    btn.mListener?.onClick(null) //onClick mPrivateFlags=1
}

Java对Kotlin嵌套类/内部类的访问

public class NestedClassTest {
    public static void main(String[] args){
        Button.ButtonState state = new Button.ButtonState();

        Button.ButtonState2 state2 = new Button().new ButtonState2();
        state2.accessOutter();

        Button btn = new Button();
        btn.setOnClickListener();
        btn.getMListener().onClick(null);
    }
}

由上面的内部类 ButtonState2 访问外部类 ButtonmPrivateFlags 变量,可知Kotlin内部类可以访问外部类的私有成员。
但有一点与Java不同,Kotlin的外部类无法访问内部类的私有成员:

但Java的外部类可以访问内部类私有成员:


   转载规则


《Kotlin嵌套类与内部类》 congwiny 采用 知识共享署名 4.0 国际许可协议 进行许可。
评论
 上一篇
Hexo + GitHub Pages使用自定义域名 Hexo + GitHub Pages使用自定义域名
域名申请在域名商那边购买域名,我选择在腾讯云购买域名。 购买成功之后,进入腾讯云的域名管理 点击解析按钮 添加以下2个记录就可以了 GitHub Pages配置到GitHub的博客仓库,点击设置,然后修改Custom domain为自己的
2019-09-19
下一篇 
Kotlin解构声明 Kotlin解构声明
解构声明:这个功能允许你展开单个复合值,并使用它来初始化多个单独的变量。任何表达式都可以出现在解构声明的右侧,只要可以对它调用所需数量的 component 函数即可。 /** * 要在解构声明中初始化每个变量,会调用名为componen
2019-09-09
  目录