嵌套类
一个类可以嵌套在另一个类里面:
class OuterClass {class NestedClass {funmethod(){println("hello")}}}funmain(){var outerClass = OuterClass.NestedClass()
outerClass.method()}
内部类
内部类与嵌套类类似,都是声明在另一个类里面,只不过多了一个关键字inner
。
class Outer {var str ="hello"innerclass InnerClass {funmethod(){println(str)println(this@Outer.str)}}}funmain(){var outer =Outer().InnerClass()
outer.method()}
嵌套类与内部类的区别与联系:
- 嵌套类:对应java内部的静态内部类(有static关键字修饰)
- 内部类:对应java内部的非静态内部类(没有static关键字修饰),可以访问外部类的属性。
局部嵌套类:定义在方法内部的类。
fungetName(): String {class LocalNestedClass {var name ="morris"}var localNestedClass =LocalNestedClass()return localNestedClass.name
}
对象表达式
kotlin中的匿名内部类使用对象表达式(object expression:)来创建。
匿名内部类是没有名字的,需要继承某个父类,或者实现了某个接口:
interface MyInterface {funprint(i: Int)}funmain(){var myInterface =object: MyInterface {overridefunprint(i: Int){println("print $i")}}
myInterface.print(1024)}
匿名内部类可以不支持显示的父类,默认为Any。
var obj =object{funmethod(name: String){println("print $name")}}
obj.method("morris")
匿名内部类可以实现一个父类或多个接口(java只能实现一个)。
interface MyInterface {funprint(i: Int)}abstractclass MyAbstract {abstractval age: Int
abstractfunmethod(name: String)}funmain(){var myclass =object:MyAbstract(), MyInterface {overridefunprint(i: Int){println("print $i")}overrideval age: Int
get()=10overridefunmethod(name: String){println("print name=$name age=$age")}}
myclass.print(1024)
myclass.method("morris")}
匿名对象只能在局部变量范围内或者被private修饰的成员变量范围内才能真正识别出其具体类型,如果匿名对象作为一个public方法的返回值或者public的属性,那么外部能识别到的只有该匿名对象的父类型,如果没有声明任何父类型,那么就是默认的Any,在这种情况下,匿名对象中声明的任何成员都是无法访问的。
class MyClass {privatevar obj =object{funhello(){println("hello")}}funtest(){
obj.hello()}}
与java中的匿名内部类不同,kotlin中的内部类可以修改外部的变量,外部的变量也不需要设置为final。
funmain(){var age =10var obj =object{funhello(){println("print ${++age}")}}
obj.hello()}
如果接口是一个函数式接口,使用lambda表达式更简洁:
val listener = ActionListener {println("clicked")}