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
}
當然屬性也是可以代理的,可以回到之前寫的看看。