7.12 嵌套类(Nested Class)
7.12.1 嵌套类:类中的类
类可以嵌套在其他类中,可以嵌套多层:
class NestedClassesDemo {
class Outer {
private val zero: Int = 0
val one: Int = 1
class Nested {
fun getTwo() = 2
class Nested1 {
val three = 3
fun getFour() = 4
}
}
}
}
测试代码:
val one = NestedClassesDemo.Outer().one
val two = NestedClassesDemo.Outer.Nested().getTwo()
val three = NestedClassesDemo.Outer.Nested.Nested1().three
val four = NestedClassesDemo.Outer.Nested.Nested1().getFour()
println(one)
println(two)
println(three)
println(four)
我们可以看出,访问嵌套类的方式是直接使用 类名.
, 有多少层嵌套,就用多少层类名来访问。
普通的嵌套类,没有持有外部类的引用,所以是无法访问外部类的变量的:
class NestedClassesDemo {
class Outer {
private val zero: Int = 0
val one: Int = 1
class Nested {
fun getTwo() = 2
fun accessOuter() = {
println(zero) // error, cannot access outer class
println(one) // error, cannot access outer class
}
}
}
}
我们在Nested类中,访问不到Outer类中的变量zero,one。
如果想要访问到,我们只需要在Nested类前面加上inner
关键字修饰,表明这是一个嵌套的内部类。
7.12.2 内部类(Inner Class)
类可以标记为 inner 以便能够访问外部类的成员。内部类会带有一个对外部类的对象的引用:
class NestedClassesDemo {
class Outer {
private val zero: Int = 0
val one: Int = 1
inner class Inner {
fun accessOuter() = {
println(zero) // works
println(one) // works
}
}
}
测试代码:
val innerClass = NestedClassesDemo.Outer().Inner().accessOuter()
我们可以看到,当访问inner class Inner
的时候,我们使用的是Outer().Inner()
, 这是持有了Outer的对象引用。跟普通嵌套类直接使用类名访问的方式区分。
7.12.3 匿名内部类(Annonymous Inner Class)
匿名内部类,就是没有名字的内部类。既然是内部类,那么它自然也是可以访问外部类的变量的。
我们使用对象表达式创建一个匿名内部类实例:
class NestedClassesDemo {
class AnonymousInnerClassDemo {
var isRunning = false
fun doRun() {
Thread(object : Runnable {
override fun run() {
isRunning = true
println("doRun : i am running, isRunning = $isRunning")
}
}).start()
}
}
}
如果对象是函数式 Java 接口,即具有单个抽象方法的 Java 接口的实例,例如上面的例子中的Runnable接口:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
我们可以使用lambda表达式创建它,下面的几种写法都是可以的:
fun doStop() {
var isRunning = true
Thread({
isRunning = false
println("doStop: i am not running, isRunning = $isRunning")
}).start()
}
fun doWait() {
var isRunning = true
val wait = Runnable {
isRunning = false
println("doWait: i am waiting, isRunning = $isRunning")
}
Thread(wait).start()
}
fun doNotify() {
var isRunning = true
val wait = {
isRunning = false
println("doNotify: i notify, isRunning = $isRunning")
}
Thread(wait).start()
}
测试代码:
NestedClassesDemo.Outer.AnonymousInnerClassDemo().doRun()
NestedClassesDemo.Outer.AnonymousInnerClassDemo().doStop()
NestedClassesDemo.Outer.AnonymousInnerClassDemo().doWait()
NestedClassesDemo.Outer.AnonymousInnerClassDemo().doNotify()
输出:
doRun : i am running, isRunning = true
doStop: i am not running, isRunning = false
doWait: i am waiting, isRunning = false
doNotify: i notify, isRunning = false
关于lambda表达式以及函数式编程,我们将在下一章中学习。
当前内容版权归 JackChan1999 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 JackChan1999 .