Kotlinクラスの特徴
Kotlinのクラスには、以下のような特徴があります。思いつくままに列挙してみます。
-
new キーワードなしでインスタンス化することができます。
- new キーワードを付けてインスタンス化するとエラーになります。
- 構成要素はプロパティとメソッド(関数)のみです。
- プロパティ
- デフォルト公開属性は public です。
- lateinit キーワードを付加すると、後から初期化可能となります。この場合には、 mutable である必要があります。すなわち可変変数キーワード var で宣言する必要があります。
- lazy キーワードを付加しても後から初期化可能です。この場合にはimmutable である必要があります。すなわち不変変数キーワード val で宣言する必要があります。
- クラス内の関数
- クラス外関数とまったく同じ方法で定義します。
- fun キーワードを付けて定義します。
- 関数はメソッドと呼ばれることもあります。
- クラスとメソッドの継承可能性はデフォルトで final です。すなわち継承を許しません。
- 継承させたい場合には明示的に open キーワードを付加します。
- クラス内に内部クラスであるインナークラスを定義できます。
- インナークラスに明示的に inner キーワードをつけて定義すると、定義したクラス内のメンバーにアクセスすることができます。
- init キーワード付きのコードブロックはコンストラクタの定義となります。すなわち、インスタンス時に実行されます。
- 同一ファイル内に複数のクラスを含めることができます。
遅延初期化
後から初期化する遅延初期化には、lateinit キーワードによるものと lazy キーワードによるものがあります。
lateinit キーワードの場合には、 mutable ですので、可変変数キーワード var で宣言する必要があります。すなわち、初期化した後から変更することができます。
lazy キーワードの場合には、 immutable ですので、不変変数キーワード val で宣言する必要があります。すなわち、初期化した後に変更することはできません。
class LateinitAndLazy {
lateinit var lateinitString: String
val lazyString: String by lazy {
val valueOfString = "This train consists 12 cars."
valueOfString
}
fun lateinitStringLength() {
lateinitString =
"Boardingn locations are indicated by white circles and No.1 through 7."
val length = lateinitString.length
println("Length of 'lateinitString' is $length" )
lateinitString = "We are soon making brief stop at Bentencho."
}
fun lazyStringLength() {
val length = lazyString.length
println("Length of 'lazyString' is $length" )
}
}
fun main( args: Array<String> ) {
LateinitAndLazy().lateinitStringLength()
LateinitAndLazy().lazyStringLength()
}
Length of 'lateinitString' is 68
Length of 'lazyString' is 28
クラスの継承
クラスはデフォルト、つまり何も指定しないで宣言すると final クラスとなり、継承を許しません。
open キーワードを明示的に付加して定義することで、定義されたクラスは継承を許します。
open class Employee( name: String, age: Int ) {
val name = name
val age = age
}
class Company: Employee( "Jhonson", 58 )
fun main(args: Array<String>) {
println(
"Name is ${Company().name} and " +
"Age is ${Company().age}."
)
}
Name is Jhonson and Age is 58.
prog.kt:6:16: error: this type is final, so it cannot be inherited from
class Company: Employee( "Jhonson", 58 )
^
インナークラスの定義
インナークラスの定義でinner キーワードをつけない場合、インナークラスを含む外のクラスのメンバーにアクセスすると、コンパイルエラーとなります。
class Outer {
private val outer: String = "Outerクラス"
class Child {
fun child() = "Childクラス"
fun errorChild() = outer //コンパイルエラー
}
inner class Inner {
fun innerFoo() = outer
}
}
fun main(args: Array<String>) {
println( Outer.Child().child() )
println( Outer().Inner().innerFoo() )
}
Childクラス
Outerクラス
innerClass.kt:6:24: error: unresolved reference: outer
fun errorChild() = outer //コンパイルエラー
^
インスタンス時の処理の定義
クラスがインスタンス化されるときに実行される処理は明示的に init キーワードブロック内に記述します。
class Baa {
val baa: Float
init {
baa = 3.14f
}
fun dispBaa() { println( "baa is $baa!" ) }
}
fun main( args: Array<String> ) {
Baa().dispBaa()
}
baa is 3.14!
Visual Studio Codeが好き
どうもMarkdownのコードのソースコードハイライトけが好きになれないです。個人的に、Visual Studio Codeの背景色とソースコードハイライトがお気に入りなのです。
LateinitAndLazy.kt : Visual Stduio Code on Windows10 Pro
Compile and Execute: Windows PowerShell on Windows10 Pro
innerClass.kt : Visual Stduio Code on Windows10 Pro
Compile and Execute: Windows PowerShell on Windows10 Pro