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 访问外部类 Button 的 mPrivateFlags 变量,可知Kotlin内部类可以访问外部类的私有成员。
但有一点与Java不同,Kotlin的外部类无法访问内部类的私有成员:
但Java的外部类可以访问内部类私有成员: