嵌套类
在一个类的内部声明一个类,叫做类嵌套。
class Outer(var name: String) {
class Inner(var log: Double, var lat: Double) {
fun print() {
println(name) // 嵌套类调用外部的属性,这里会编译报错
}
}
}
内部类
声明为inner
的嵌套类叫做内部类,内部类可以调用外部类的属性,但是嵌套类却不行。
class Outer(var name: String) {
inner class Inner(var log: Double, var lat: Double) {
fun print() {
println(name) // 只有内部类才能访问外部类,如果嵌套类没有声明为inner,会编译报错
}
}
}
匿名内部类
匿名内部类,就是在一个类内部,直接实例化一个类对象当做参数的类
class Outer(var name: String) {
fun main(args: Array<String>) {
setListener(object : Listener { // 内部类类型是接口,无需带括号,因为没有构造函数
override fun onChange() {
TODO("not implemented")
}
})
}
}
interface Listener {
fun onChange()
}
匿名内部类需要注意的几个事项
- 使用时,实例化采用
object
关键字,使用冒号后面紧跟着内部类; - 如果匿名内部类类型是一个接口(
interface
),那么接口名后面无需带括号(如上示例) - 如果内部类类型是抽象类(
abstract class
),那么接口名后面需要带括号,必要时需要带参数
class Outer(var name: String) {
fun main(args: Array<String>) {
setListener(object : Listener() { // 内部类类型是抽象类,有构造函数,需要带括号,必要时需要参数
override fun onChange() {
TODO("not implemented")
}
})
}
}
abstract class Listener {
abstract fun onChange()
}
- 如果内部类类型是普通类,那么该类必须是
open
的,如果需要重新里面的方法,重写的方法也必须是open
的
class Outer(var name: String) {
fun main(args: Array<String>) {
setT(object : T(){ // 这里需要带括号,T类必须是open的,
override fun t() { // 所覆盖的方法也必须是open的
}
})
}
fun setT(t: T) {
}
}
open class T {
open fun t() {
}
}