クラスの継承
- インタフェースに準拠するときと同じように、クラス名の定義の後に
:
でつなげる
- 継承元:スーパークラス、継承先:サブクラス
- 継承元のクラスは
open
を指定しないと継承不可
open class Person(val name: String) {
fun introduceMyself() {
println("I am $name")
}
}
class Student(name: String, val id: Long): Person(name)
メンバのオーバーライド
- オーバーライドもデフォルトで禁止されており、プロパティやメソッドに
open
を付ける必要がある
- スーパークラスのメンバを呼び出すときは
super.メンバ
open class Person(val name: String) {
open fun introduceMyself() {
println("I am $name")
}
}
class Student(name: String, val id: Long): Person(name) {
override fun introduceMyself() {
super.introduceMyself()
println("id=$id")
}
}
val student = Student("hicka04", 123)
student.introduceMyself() // I am hicka04 \n id=123
スーパータイプとサブタイプ
- クラスを定義することで型を得られる
- スーパークラス:スーパータイプ
- サブクラス:サブタイプ
- サブタイプのオブジェクトは、スーパータイプのオブジェクトとして扱うことができる
- スーパータイプにないメンバはアクセス不能
- アクセスすると実態はサブタイプの方にアクセスしている
val person: Person = Student("hicka04", 123)
person.introduceMyself() // I am hicka04 \n id=123
person.id // コンパイルエラー
Any
- すべてのクラスが継承している暗黙的な型
- すべてのオブジェクトに共通する基本的なメソッドを提供している
public open fun toString(): String
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
抽象クラス
- メンバのオーバーライドをサブクラスに強制する仕組み
- メソッドやプロパティに
abstruct
をつける → 抽象メンバ
- 抽象メンバをもつクラスは抽象クラスで、インスタンス化はできない
-
abstruct
がついている抽象メンバはオーバーライド必須なのでopen
キーワードは不要
abstract class Greeter(val target: String) {
abstract fun sayHello()
}
class EnglishGreeter(target: String): Greeter(target) {
override fun sayHello() {
println("Hello, $target")
}
}
class JapaneseGreeter(target: String): Greeter(target) {
override fun sayHello() {
println("こんにちは、$target")
}
}
EnglishGreeter("Kotlin").sayHello() // Hello, Kotlin
JapaneseGreeter("Java").sayHello() // こんにちは、Java
可視性
パッケージ
- Javaと同様にパッケージで名前空間を区切る
- パッケージ直下には以下の要素を宣言できる
- 関数
- プロパティ
- クラス
- インタフェース
- オブジェクト
- 同一のパッケージ内に同名のクラスを複数定義することはできない
⇔異なるパッケージであれば同名のクラスを定義可能
package sample.hoge
class Foo
-
Foo
はsample.hoge
に属する
- 同一パッケージ内であれば
Foo
でアクセス可能
- 異なるパッケージから呼ぶときは
sample.hoge.Foo
でアクセスする必要がある
-
import
することでFoo
だけで呼べるようになる
package sample.fuga
import sample.hoge.Foo
import sample.fuga.Buz as Beer
class Baz
class Bar {
fun doSomething() {
sample.hoge.Foo()
Foo() // importしてるのでこれでOK
Berr() // 別名インポートしているのでOK
}
}
トップレベルにおける可視性修飾子
- パッケージ直下に宣言できる関数やクラスなどに可視性修飾子をつけることで公開範囲を調整できる
修飾子 |
公開範囲 |
備考 |
public |
公開範囲に制限はなく、どこからでもアクセス可 |
デフォルト |
internal |
同一のモジュール内に限り全公開 |
|
private |
同一ファイル内のみアクセス可能 |
|
クラスにおける可視性修飾子
クラスやインタフェースのメンバにつける可視性修飾子
修飾子 |
公開範囲 |
備考 |
public |
公開範囲に制限はなく、どこからでもアクセス可 |
デフォルト |
internal |
同一のモジュール内に限り全公開 |
|
protected |
同一クラス内とサブクラス内からアクセス可 |
|
private |
同一クラス内のみアクセス可能 |
|
// プライマリコンストラクタにつけるときは`constructor`を省略できない
open class Hoge private constructor()
← 文法詳解 - クラスとそのメンバ || 文法詳解 - インタフェース →