1. 内部类
内部类是内嵌类在kotlin是不一样的,比如下面是内嵌类
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() // == 2
下面是内部类
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() // == 1
还可以使用object作为内部类
window.addMouseListener(object: MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
也可以使用lambda表达式
val listener = ActionListener { println("clicked") }
2. 枚举类
kotlin的枚举类和java基本一样
enum class ProtocolState {
WAITING {
override fun signal() = TALKING
},
TALKING {
override fun signal() = WAITING
};
abstract fun signal(): ProtocolState
}
3.对象
有些时候我们想创建一个轻微修改的类对象,但是又不想创建一个新类去继承,那么这个时候就可以用object来修饰。
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
其实说白了,object就是匿名类的意思
open class A(x: Int) {
public open val y: Int = x
}
interface B {...}
val ab: A = object : A(1), B {//可以是指定类型的
override val y = 15
}
fun foo() {
val adHoc = object {//也可以是完全没有指定类型的。。
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
需要注意:匿名对象只能用户本地声明或者private声明,看下面例子
class C {
// Private function, so the return type is the anonymous object type
private fun foo() = object {
val x: String = "x"
}
// Public function, so the return type is Any
fun publicFoo() = object {
val x: String = "x"
}
fun bar() {
val x1 = foo().x // Works
val x2 = publicFoo().x // ERROR: Unresolved reference 'x'
}
}
跟java一样可以如下访问,但是不需要像java一样设置为final
fun countClicks(window: JComponent) {
var clickCount = 0
var enterCount = 0
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
clickCount++
}
override fun mouseEntered(e: MouseEvent) {
enterCount++
}
})
// ...
}
还可以作为单例模式使用
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}
val allDataProviders: Collection<DataProvider>
get() = // ...
}
DataProviderManager.registerDataProvider(...)
还可以使用companion关键字修饰,变成Companion Objects
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
val instance = MyClass.create()
class MyClass {
companion object {
}
}
val x = MyClass.Companion
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
感觉object这个东西很灵活,用起来很方便。
4. 代理
在Java中,有时候我们需要代理某个对象的方法,比如
class A{
void print(){
System.out.println();
}
}
class B{
A a;
void print(){
a.print();
}
}
但是在kotlin,只要如下写:
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b //把b对象的方法交给Derived代理,所以代理也要慎用
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // prints 10
}
当然属性也是可以代理的,可以回到之前写的看看。