kotlin对象表达式(java匿名内部类)
1.概念
kotlin使用对象表达式代替java的匿名内部类语法。
语法格式:
object : [0-N个父类型] {
//对象表达式类体
}
2.特点
- 对象表达式不能是抽象类;
- 对象表达式不能定义构造器;
- 对象表达式可以包含内部类(inner),但不能包含嵌套类;
- 对象表达式可以访问或修改所在局部范围的变量(相比之下,java只能访问effectivley final局部变量)。
3.定义对象表达式
fun main() {
var localParam = 1
/**
* 定义一个对象表达式,实现了Sports接口
*/
val badminton = object : Sports {
override val name: String
get() = "羽毛球"
}
println("运动类型:${badminton.name}")//运动类型:羽毛球
/**
* 定义一个对象表达式,没有任何父类
*/
val running = object {
val name = "短跑"
fun playRules() {
println("在跑道上比赛")
}
/**
* 访问、修改局部变量
*/
fun changeLocalParam() {
localParam = 2
}
}
println("运动类型:${running.name}")//运动类型:短跑
running.playRules()//在跑道上比赛
running.changeLocalParam()
println("修改后的局部变量:$localParam")//修改后的局部变量:2
/**
* 定义一个对象表达式,可以继承0~1个父类,可以实现0~N个接口
*/
val basketball = object : Ball(true), Sports {
override val name: String
get() = "篮球"
override fun playRules() {
println("在篮球场上比赛")
}
/**
* 可以定义内部类,但不可以定义嵌套类
*/
inner class FamousBasketballPlayers(val playerNames: ArrayList<String>)
}
println("运动类型:${basketball.name}")//运动类型:篮球
println("${basketball.isBelongSports}")//true
basketball.playRules()//在篮球场上比赛
val famousPlayers = basketball.FamousBasketballPlayers(ArrayList(listOf("乔丹", "詹姆斯", "科比")))
println(famousPlayers.playerNames)//[乔丹, 詹姆斯, 科比]
}
/**
* 定义一个运动接口
*/
interface Sports {
val name: String
}
/**
* 定义一个球类抽象类
*/
abstract class Ball(val isBelongSports: Boolean) {
abstract fun playRules()
}
4.对象表达式可以被编译器识别类型的情况
- 对象表达式声明在方法/函数局部范围内,被当做局部变量时,可以被编译器识别出来真实类型;
- 对象表达式不是局部变量时,使用private修饰的对象表达式才能被编译器识别出来真实类型,其他权限符修饰只会被当成父类类型的一个实例,如果既没有父类也没有权限符修饰,会被当成Any的一个实例。
/**
* 定义一个类
*/
class RecognizeObjectExpression {
/**
* 定义一个父类抽象类
*/
abstract class Parent {
abstract val parentName: String
}
/**
* private修饰的对象表达式,可以被编译器识别出类型
*/
private val expression1 = object : Parent() {
override val parentName: String
get() = "expression1父类名字"
val type = "private修饰点的对象表达式"
}
/**
* public修饰的对象表达式,不可以被编译器识别出类型,
*/
val expression2 = object : Parent() {
override val parentName: String
get() = "expression2父类名字"
val type = "public修饰的对象表达式"
}
fun recognize() {
val localExpression3 = object : Parent() {
override val parentName: String
get() = "localExpression3父类名字"
val type = "局部变量对象表达式"
}
//private修饰的对象表达式,可以直接被识别出真实类型,调用该对象表达式的成员
println(expression1.type)//private修饰点的对象表达式
//非private修饰的对象表达式,不能被识别出真实类型,不能直接调用对象表达式的成员
// println(expression2.type)//编译不通过
println(expression2.parentName)//但可以知道父类是什么类型
println(localExpression3.type)//局部对象表达式,可以直接被识别出真实类型
}
}
fun main() {
val recognizeObjectExpression = RecognizeObjectExpression()
recognizeObjectExpression.recognize()
}