Skip to content

Instantly share code, notes, and snippets.

@ezura
Last active July 18, 2017 05:39
Show Gist options
  • Save ezura/12cd5fdffdcf93ece54f27c72a090d42 to your computer and use it in GitHub Desktop.
Save ezura/12cd5fdffdcf93ece54f27c72a090d42 to your computer and use it in GitHub Desktop.
kotlin 可視性実験
class A {
private fun f() = print("private")
fun _f() = f() // use `private fun f()`
}
fun A.f() = print("extension")
fun A._f() = print("extension _f") // ignored 😖
/*
val a = A()
a.f() // extension
a._f() // private
*/
class A {
// private fun f() = print("private")
fun _f() = f() // use extension `fun f()`
}
fun A.f() = print("extension")
/*
val a = A()
a.f() // extension
a._f() // extension
*/
class C {
private fun f() = print("private")
}
// error! recursive call
// fun C.f() = f()
// error! cannnot access `f`. it is private in `C`
// fun C._f() = f()
open class D {
fun f() = print("Super class: private")
}
fun D.f() = print("Super class: extension f")
fun D._f() = print("Super class: extension _f")
class _D: D() {
// private fun f() = print("Sub class: private")
// !error: overrides nothing
// override fun _f() = f() // use extension `fun f()`
}
fun _D.f() = print("Sub class: extension")
fun _D._f() = print("Sub class: extension _f")
/*
import accessControl.*
_D().f() // Super class: private
_D()._f() // Sub class: extension _f
*/
class E {
fun f() = print("class")
}
fun E.f(): String = "extension _f"
/*
E().f()
class
val s: String = E().f()
error: type mismatch: inferred type is Unit but String was expected
val s: String = E().f()
*/
@ezura
Copy link
Author

ezura commented Jul 4, 2017

考察

  • extension で生やした場合、関数の重複が可能。優先度の高いものが使われる
    • 優先度: class 内の宣言 > extension
    • accessControl1.kt:7 は、存在するけれど、優先度の高い同名メソッドがあるので使われない
  • extension で生やした関数はサブタイプでも使える。class 宣言内で書いた場合と異なる点がある
    • override の対象でない
    • super type で拡張した関数を sub type で再度拡張して上書きできる (override 指定は不要)
    • super type の class 宣言内で宣言した function の方が、extension より優先されて使われる (継承によって、上記の優先度に影響はなかった)
  • 返り値が異なる function も同一と見なされる

動作メモ

  • 同じクラス内(extension は除くという方が厳密?)では private fun fが呼ばれる
  • private fun f が見える場所でも extension した fun f は見えている(accessControl2.kt で確認)けれど、private fun f が優先されている
  • private fun f が見えない場所だとextensionした fun f が使われる

@ezura
Copy link
Author

ezura commented Jul 4, 2017

Warning:(13, 7) Kotlin: Extension is shadowed by a member: public final fun _f(): Unit
って言われてるな…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment