このチュートリアルでは、Kotlinのオブジェクト指向プログラミングの概念について説明します。Kotlinのクラスについて詳しく説明します。また、Kotlinのコンストラクタ、アクセス修飾子、抽象クラスについても見ていきます。
Kotlinのクラス
クラスは、関数やプロパティをグループ化する定義であり、Kotlinではキーワード
class
の後にクラス名が続きます。本体は中括弧の内側に記述されます。
class FirstClass {
}
クラスのインスタンスは、次のように生成されます:
val firstClass = FirstClass()
var new = FirstClass() //here new is the name of the var.
Javaとは異なり、Kotlinではnew
はキーワードではありません。Kotlinでは、クラスはデフォルトでfinalです。したがって、Javaでの上記の定義の相当する部分は次のようになります:
public final class FirstClass {
}
したがって、Kotlinではデフォルトでクラスは継承できません。クラスを非finalにするには、キーワードopen
を追加する必要があります。
open class Me{
}
open
アノテーションは、他のクラスがこのクラスを継承できるようにします。
Kotlinのクラスの例
クラスを作成して、いくつかの関数とプロパティを持たせましょう。そのクラスの関数とプロパティにどのようにアクセスするかを見てみましょう。さらに、メンバープロパティを設定する方法も見てみましょう。
class User {
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
fun main(args: Array<String>) {
val user = User()
println(user.loggedIn) //false
user.logOn()
println(user.loggedIn) //true
user.logOff()
println(user.loggedIn) //false
user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.
}
関数main
はTest.kt
クラスに属しています。メンバーと関数にアクセスするには、ドット演算子を使用する必要があります。val
プロパティは、ドット演算子を使用して再設定することはできません。
Kotlin init
Kotlinの初期化ブロックは、以下に示すように定義されています。
class User {
init{
print("Class instance is initialised.")
}
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
init
ブロック内のコードは、クラスがインスタンス化されるときに最初に実行されます。 init
ブロックは、次に示すように任意の種類のコンストラクタでクラスがインスタンス化されるたびに実行されます。 クラス内に複数の初期化ブロックを記述できます。 これらは、次に示すように順次実行されます。
class MultiInit(name: String) {
init {
println("First initializer block that prints ${name}")
}
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array) {
var multiInit = MultiInit("Kotlin")
}
//以下がログコンソールに出力されます。
//Kotlinを出力する最初のイニシャライザーブロック
//6を出力する2番目のイニシャライザーブロック
Kotlinのクラスでは、also
関数を使用して、宣言自体でプロパティを出力することができます。 以下に示すように。
class MultiInit(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array) {
var multiInit = MultiInit("Kotlin")
}
//以下が出力されます。
//最初のプロパティ:Kotlin
//Kotlinを出力する最初のイニシャライザーブロック
//2番目のプロパティ:6
//6を出力する2番目のイニシャライザーブロック
Kotlinコンストラクタ
Kotlinのコンストラクタは、プロパティを初期化するために使用される特別なメンバー関数です。Kotlinのコンストラクタは、Javaとは異なる方法で書かれ、構造化されています。デフォルトでは、以下に示すようにクラスには空のコンストラクタがあります:
class Student {
var name: String
val age : Int
init {
name = "Anupam"
age = 24
}
init {
name = "Anupam Chugh"
//age = 26
}
}
fun main(args: Array) {
val student = Student()
println("${student.name} age is ${student.age}")
student.name = "Your"
//student.age = 26 //コンパイルされません。ageはvalです
println("${student.name} age is ${student.age}")
}
//以下がコンソールに表示されます:
//Anupam Chugh age is 24
//Your age is 24
プライマリコンストラクタ
Kotlinのプライマリコンストラクタは、以下に示すようにクラスヘッダー自体で定義されます。
class User(var name: String, var isAdmin: Boolean) {
init {
name = name + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $isAdmin")
}
}
プライマリコンストラクタの定義はクラスヘッダー内に配置されます。注意: var
として指定されていない限り、デフォルトでは、コンストラクタ引数は val
です。
class User(name: String, isAdmin: Boolean)
上記のコードでは、nameとisAdminの両方を再代入することはできません。代わりに、以下に示すようにクラス内のメンバープロパティにコンストラクタ引数を割り当てることもできます。
class User(name: String, val isAdmin: Boolean) {
var username = name
val _isAdmin = isAdmin
init {
username= username + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $_isAdmin")
}
}
fun main(args: Array) {
var user = User("Anupam",false)
user.isAdmin = true //won't compile since isAdmin is val
user._isAdmin = true //won't compile. Same reason.
user = User("Pankaj",true)
}
//ログコンソールに以下が表示されます。
//Author Name is Anupam. Is Admin? false
//Author Name is Pankaj. Is Admin? true
Kotlinのコンストラクタデフォルト値
Kotlinでは、以下に示すように、コンストラクタ自体でデフォルト値を指定することができます。
class User(name: String, var website: String = "JournalDev") {
init {
println("Author $name writes at $website")
}
init {
website = website + ".com"
println("Author $name writes at $website")
}
}
fun main(args: Array) {
var user = User("Anupam","JournalDev")
user = User("Pankaj","JournalDev")
}
//以下がコンソールに表示されます:
//著者アヌパムはJournalDevで執筆しています
//著者アヌパムはJournalDevで執筆しています.com
//著者パンカジはJournalDevで執筆しています
//著者パンカジはJournalDevで執筆しています.com
セカンダリコンストラクタ
セカンダリコンストラクタは、キーワードconstructor
を前置してクラスの本体に記述されます。次の例が同じことを示しています。
class Student {
var name: String
val age : Int
constructor(name: String, age: Int)
{
this.name = name
this.age = age
}
fun printDetails()
{
println("Name is $name and Age is $age")
}
}
fun main(args: Array) {
var student = Student("Anupam", 24)
student.printDetails()
}
//以下がコンソールに印刷されます。
//名前はアヌパムで、年齢は24歳です
セカンダリコンストラクタの最も一般的な使用法は、サブクラスで、クラスを異なる方法で初期化する必要がある場合です。クラスにプライマリコンストラクタが含まれている場合、セカンダリコンストラクタはその宣言でそれを参照する必要があります。宣言はthis
キーワードを使用して行われます。
class Student(var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
//以下がログコンソールに印刷されます:
//名前はアヌパムで、年齢は24歳です
//名前はアヌパムで、年齢は24歳です Skill is Kotlin
init
ブロックはメンバープロパティskill
を初期化するために使用されます。セカンダリコンストラクタは: this
を使用してプライマリコンストラクタに委任しています。
カスタムのゲッターとセッター
これまでクラスのプロパティにはクラスのインスタンスにドット演算子を使用してアクセスし、変更してきました。アクセスをカスタマイズするためにset
およびget
構文を使用してみましょう。
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
print(value)
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "Kotlin Classes"
name.post = ""
name.post = "Kotlin Data Classes Our Next Tutorial"
}
以下がログコンソールに表示されます:
Kotlin Classes
Exception in thread "main" java.lang.IllegalArgumentException: Enter a valid name
at Name.setPost(Test.kt:16)
at TestKt.main(Test.kt:78)
セッター内のfield
変数は以前の値を保存します。ゲッターを追加しましょう。
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
}
get() {
return field.capitalize()
}
}
fun main(args: Array) {
var name = Name()
name.post = "kotlin classes"
println(name.post)
name.post = "kotlin data Classes our next Tutorial"
println(name.post)
}
//以下が表示されます:
//Kotlinクラス
//Kotlinデータクラスは次のチュートリアル
capitalize()
は文字列の最初の文字を大文字にします。注意: プロパティがval
である場合、set
メソッドはコンパイルされません。
Kotlinの可視性修飾子
- Public:この修飾子を持つクラス、関数、プロパティ、インターフェース、またはオブジェクトは可視で、どこからでもアクセスできます。
- プライベート: この修飾子で定義されたクラス/関数は、同じファイル内からのみアクセスできます。 この修飾子を持つクラス/関数のメンバー/プロパティは、そのブロック内からのみアクセスできます。
- 保護された:この修飾子は、同じくプライベートと同じですが、サブクラス内での可視性とアクセスを許可します。
- 内部:この修飾子を持つクラス/インターフェース/関数は、同じモジュール内でのみアクセスできます。
可視性修飾子は、コンストラクタにも適用されます。プライマリコンストラクタに修飾子を割り当てるには、クラスヘッダー内のコンストラクタとともにキーワードconstructor
を指定する必要があります。
class Student private constructor (var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
fun main(args: Array) {
var student = Student("Anupam",24,"Kotlin")
student.printDetails()
}
//prints
//名前はアヌパムで、年齢は24、スキルはKotlin
プライベートコンストラクタはクラスの外部から呼び出すことはできません。 上記のコードでは、セカンダリコンストラクタを使用してのみ、異なる関数内でクラスのインスタンス化ができます。
Kotlin抽象クラス
Javaと同様に、Kotlinでは抽象クラスを宣言するためにabstract
キーワードが使用されます。 抽象クラスはインスタンス化できませんが、サブクラスによって継承されることができます。 デフォルトでは、抽象クラスのメンバーは非抽象ですが、それ以外が記述されていない限り。
abstract class Person(name: String) {
init {
println("Abstract Class. init block. Person name is $name")
}
abstract fun displayAge()
}
class Teacher(name: String): Person(name) {
var age : Int
init {
age = 24
}
override fun displayAge() {
println("Non-abstract class displayAge function overridden. Age is $age")
}
}
fun main(args: Array) {
val person = Teacher("Anupam")
person.displayAge()
}
//以下がコンソールに出力されます。
//抽象クラス。 初期化ブロック。 人の名前はアヌパム
//非抽象クラス。 年齢は24
注意: 抽象クラスはデフォルトでopen
です。したがって、サブクラス化を許可するためにopen
修飾子を追加する必要はありません。override
キーワードは、サブクラスでメソッドをオーバーライドするために使用されます。このチュートリアルでは、Kotlinのクラスの基本をカバーしました。データクラス、シールドクラス、継承など、まだたくさんあります。これらについては、今後のチュートリアルでカバーします。参考文献:Kotlinドキュメント
Source:
https://www.digitalocean.com/community/tutorials/kotlin-class-constructor