在实际开发中,用到内部类的地方是很多的。比如说:
- 对于
Android开发来说,列表适配器(adapter)中的ViewHolder类,就是一个内部类。- 根据后台开发人员提供的
json字符串生成的对象中,也包含另外一个对象,这也是一个内部类。
一、嵌套类
上面提到的两种情况,是在开发中最常见的。当然,说到内部类,就必须说道另一个概念嵌套类,所谓的嵌套类:即指一个类可以嵌套在其他类中。
例:
class Other{ // 外部类
val numOuther = 1
class Nested { // 嵌套类
fun init(){
println("执行了init方法")
}
}
}
fun main(args: Array<String>) {
Other.Nested().init() // 调用格式为:外部类.嵌套类().嵌套类方法/属性
}
输出结果为:
执行了init方法
注意:
- 调用嵌套类的属性或方法的格式为:
外部类.嵌套类().嵌套类方法/属性。在调用的时候嵌套类是需要实例化的。- 嵌套类不能使用外部类的属性和成员。
二、内部类
在上面的例子中讲解了嵌套类的使用,而内部类和嵌套类还是有一定的区别的,而且内部类是有特定的关键字去声明的。
2.1、关键字
声明一个内部类使用
inner关键字。 声明格式:inner class 类名(参数){}
例:
class Other{ // 外部类
val numOther = 1
inner class InnerClass{ // 嵌套内部类
val name = "InnerClass"
fun init(){
println("我是内部类")
}
}
}
fun main(args: Array<String>) {
Other().InnerClass().init() // 调用格式为:外部类().内部类().内部类方法/属性
}
注意:
- 调用内部类的属性或方法的格式为:
外部类().内部类().内部类方法/属性。在调用的时候内部类是需要实例化的。- 内部类能使用外部类的属性和成员。
2.2、匿名内部类
作为一名
Android开发者,对匿名内部类都不陌生,因为在开发中,匿名内部类随处可见。比如说Button的OnClickListener,ListView的单击、长按事件等都用到了匿名内部类。 一般的使用方式为定义一个接口,在接口中定义一个方法。
例:
class Other{
lateinit private var listener : OnClickListener
fun setOnClickListener(listener: OnClickListener){
this.listener = listener
}
fun testListener(){
listener.onItemClick("我是匿名内部类的测试方法")
}
}
interface OnClickListener{
fun onItemClick(str : String)
}
fun main(args: Array<String>){
// 测试匿名内部类
val other = Other()
other.setOnClickListener(object : OnClickListener{
override fun onItemClick(str: String) {
// todo
println(str)
}
})
other.testListener()
}
输出结果为:
我是匿名内部类的测试方法
遗留的问题
在上面实现的匿名内部类是很常规的用法以及写法。在我们的实际开发当中也是大家熟知的写法。但是在我们实际开发当中,会引入
lambda语法糖,让我们的项目支持lambda语法,简化代码量。在这里我也是想把用**lambda语法实现匿名内部类实现的代码贴出来**。
三、局部类
所谓局部类,这一点和
Java是一致的。即定义在方法(函数)中的类。
例:
class Other{ // 外部类
val numOther = 1
fun partMethod(){
var name : String = "partMethod"
class Part{
var numPart : Int = 2
fun test(){
name = "test"
numPart = 5
println("我是局部类中的方法")
}
}
val part = Part()
println("name = $name \t numPart = " + part.numPart + "\t numOther = numOther")
part.test()
println("name = $name \t numPart = " + part.numPart + "\t numOther = numOther")
}
}
fun main(args: Array<String>) {
// 测试局部类
Other().partMethod()
}
输出结果为:
name = partMethod numPart = 2 numOther = 1
我是局部类中的方法
name = test numPart = 5 numOther = 1
通过上面的实例:我们可以看出:
- 局部类只能在定义该局部类的方法中使用。
- 定义在实例方法中的局部类可以访问外部类的所有变量和方法。但不能修改
- 局部类中的可以定义属性、方法。并且可以修改局部方法中的变量。