[Swift]「クラス」

本記事では、クラスについて基本概念から始め、クラスの作成方法、プロパティとメソッドの使い方、継承やポリモーフィズムの高度な機能まで説明します。

目次

クラスとは?

クラスは、オブジェクト指向プログラミングにおける重要な概念です。
クラスは、オブジェクトの設計図とも言える存在であり、同じクラスから複数のインスタンスオブジェクト)を作成することができます。

クラスの作成とインスタンス化

STEP
クラスの作成

クラスを作成するには、classキーワードを使用します。

class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    func sayHello() {
        print("Hello, my name is \(name)!")
    }
}
  • このコードは、Personというクラスを定義しています。Personクラスには以下のプロパティメソッドが含まれています。
  • name: String型のプロパティ。人物の名前を表します。
  • age: Int型のプロパティ。人物の年齢を表します。
  • init(name:age:): イニシャライザ。名前と年齢を受け取ってインスタンスを初期化します。
  • sayHello(): メソッド。挨拶をするためのメソッドで、名前を含んだメッセージを出力します。
STEP
インスタンスの作成
let person1 = Person(name: "John", age: 25)
let person2 = Person(name: "Alice", age: 30)
  • letキーワードを使用してperson1person2という名前のPersonクラスのインスタンスを作成しています。
  • それぞれのインスタンスはnameageのプロパティを持ち、与えられた値で初期化されます。
  • ここではperson1は”John”という名前で25歳、person2は”Alice”という名前で30歳のインスタンスが作成されます。
STEP
プロパティ、メソッドの値の出力
print(person1.name) //出力結果 John
print(person1.age)  //出力結果 25
print(person1.name) //出力結果 Alice
print(person2.age)  //出力結果 30
person1.sayHello() 
//出力結果: Hello, my name is John!

person2.sayHello() 
//出力結果: Hello, my name is Alice!

クラスの変数とメソッド

インスタンス変数・メソッド

インスタンス変数は、クラスインスタンスごとに異なる値を持つ変数です。
インスタンスメソッドは、インスタンス変数に対して処理を行うメソッドです。

class Person {
    var name: String // インスタンス変数
    
    init(name: String) {
        self.name = name
    }
    
    func sayHello() {  // インスタンスメソッド
        print("Hello, my name is \(name)!")
    }
}
  1. var name: String:
    Personクラス内に存在するインスタンス変数です。この変数は文字列型のデータを格納します。
  2. init(name: String) { ... }:
    Personクラスのイニシャライザです。引数としてnameを受け取り、self.nameにその値を代入してインスタンスを初期化します。
  3. func sayHello() { ... }:
    Personクラス内に存在するインスタンスメソッドです。このメソッドは「Hello, my name is (name)!」というメッセージを出力します。nameはインスタンス変数の値を参照しています。
let person1 = Person(name: "John")
person1.sayHello() 
//出力結果: Hello, my name is John!

let person2 = Person(name: "Emily")
person2.sayHello() 
//出力結果: Hello, my name is Emily!
  • let person1 = Person(name: "John")
    Personクラスのインスタンスを作成しています。
    nameには”John”が渡され、sayHello()メソッドを呼び出すことでその結果が出力されます。
  • let person2 = Person(name: "Emily")
    別のPersonクラスのインスタンスを作成しています。
    こちらも同様にsayHello()メソッドを呼び出すことでその結果が出力されます。

クラス変数・メソッド

クラス変数は、クラス全体で共有される変数です。
クラスメソッドは、クラス変数に対して処理を行うメソッドです。

class Math {
    static var pi: Double = 3.14159 // クラス変数
    
    static func square(_ number: Int) -> Int {  //クラスメソッド
        return number * number
    }
}

static var pi: Double = 3.14159:
Mathクラス内に存在するクラス変数です。

static を使って定義されたプロパティは、クラス自体に関連付けられます。つまり、そのプロパティは特定のインスタンスに属するものではなく、クラス全体で共有される値を持ちます。この変数には円周率πの値が格納されています。

static func square(_ number: Int) -> Int { ... }:
Mathクラス内に存在するクラスメソッドです。

static を使って定義されたメソッドクラス自体に関連付けられます。これにより、クラスのインスタンスを作成せずに、直接クラス名を使用してメソッドを呼び出すことができます。

print(Math.pi) 
//出力結果: 3.14159

let squaredNumber = Math.square(5)
print(squaredNumber) 
//出力結果: 25
  1. print(Math.pi):
    Mathクラスのクラス変数であるpiの値を出力しています。
  2. let squaredNumber = Math.square(5):
    Mathクラスのクラスメソッドであるsquare(_:)を使用して、引数として5を渡し、その結果をsquaredNumberに代入しています。

以上がクラスプロパティメソッドの使い方の解説です。正しくプロパティメソッドを使い分けることで、より効果的なコードを記述できます。

クラスの初期化方法

STEP
デフォルトイニシャライザ

デフォルトイニシャライザは、クラスプロパティを初期化するためのデフォルトの方法です。
クラスの定義によって自動的に提供されます。

class Person {
    var name: String
    var age: Int
    
    init() {
        name = ""
        age = 0
    }
}
  1. var name: Stringvar age: Int:
    Personクラス内に存在するインスタンス変数です。
  2. nameは文字列型のデータ、ageは整数型のデータを格納します。
  3. init() { ... }: Personクラスのイニシャライザです。
  4. このイニシャライザは引数を取らず、インスタンスが作成される際に実行されます。
  5. nameageの初期値をそれぞれ空文字列とゼロに設定しています。
let person = Person()

print(person.name) 
//出力結果: ""
print(person.age)
//出力結果: 0
  1. let person = Person(): Personクラスのインスタンスを作成しています。
  2. この際、引数なしでイニシャライザが呼び出されnameageの初期値が設定されます。
  3. print(person.name): personnameプロパティを出力しています。
  4. 初期化時に空文字列が代入されているため、出力結果は空文字列(””)になります。
  5. print(person.age): personageプロパティを出力しています。
  6. 初期化時にゼロが代入されているため、出力結果は0になります。
STEP
カスタムイニシャライザ

カスタムイニシャライザは、特定のパラメータを受け取り、インスタンスを初期化するためのイニシャライザです。

class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}
  1. var name: Stringvar age: Int:
    Personクラス内に存在するインスタンス変数です。
  2. nameは文字列型のデータ、ageは整数型のデータを格納します。
  3. init(name: String, age: Int) { ... }:
    Personクラスのイニシャライザです。
  4. このイニシャライザは2つの引数、nameageを受け取りそれぞれのプロパティに代入していますselfはクラス自体を指し示すために使用されます。
let person = Person(name: "John", age: 25)

print(person.name) 
//出力結果: John
print(person.age) 
//出力結果: 25
  1. let person = Person(name: "John", age: 25):
    Personクラスのインスタンスを作成しています。
  2. イニシャライザには”name”と”age”という引数が与えられ、それぞれのプロパティに指定された値が代入されます。この例では、名前が”John”で年齢が25のインスタンスが作成されます。
  3. print(person.name): personnameプロパティを出力しています。
    インスタンス作成時に指定した名前である”John”が表示されます。
  4. print(person.age): personageプロパティを出力しています。
    インスタンス作成時に指定した年齢である25が表示されます。

クラスの継承とポリモーフィズム

クラスの継承

継承は、既存のクラスをベースにして新しいクラスを作成する機能です。
継承を使用することで、既存のクラスプロパティメソッド継承し、新しいクラスで追加や変更を行うことができます。

STEP
SuperClass(親)→継承元の作成
class Enemy {
    var health = 100
    var attackStrength = 10
    
    func move() {
        print("Walk forwards.")
    }
    
    func attack() {
        print("Land a hit, does \(attackStrength) damage.")
    }
}
  • var health = 100var attackStrength = 10:
    Enemy クラス内に存在するインスタンス変数です。
    health は敵の体力、attackStrength は敵の攻撃力を表します。
  • func move() { ... }:
    Enemy クラス内に存在するメソッドです。
    このメソッドは「前進する」という動作を出力します。
  • func attack() { ... }:
    Enemy クラス内に存在するメソッドです。
    このメソッドは攻撃を行い、その攻撃力に基づいたダメージを出力します。
STEP
SubClass(子)の作成

SubClassSuperClassのすべてのプロパティとメソッドにアクセスできる

class Dragon: Enemy {
    var wingSpan = 2
}
  • このクラスは Enemy クラスを継承しています。
  • var wingSpan = 2: Dragon クラスに存在するインスタンス変数です。
    wingSpan はドラゴンの翼の長さを表します。

Dragonクラス(子)はEnemyクラス(親)を継承する。
さらに、新たなプロパティwingSpanを設定することができる。

let dragon = Dragon()

dragon.move()
//Walk forwards.

dragon.attack()
//Land a hit, does 10 damage.

print(dragon.wingSpan)
//2
  1. let dragon = Dragon():
    Dragon クラスのインスタンスを作成しています。
  2. dragon.move():
    Dragon インスタンスの move() メソッドを呼び出しています。
    出力結果は「Walk forwards.」となります。
  3. dragon.attack():
    Dragon インスタンスの attack() メソッドを呼び出しています。
    出力結果は「Land a hit, does (attackStrength) damage.」となります。
    attackStrengthEnemy クラスから継承されたプロパティで、10という値が表示されます。
  4. print(dragon.wingSpan):
    Dragon インスタンスの wingSpan プロパティの値を出力しています。
    出力結果は2となります。

ポリモーフィズム

ポリモーフィズムは、異なるクラスが同じメソッド名を持ち、それぞれ独自の実装を行う機能です。
これにより、同じメソッド名を使用して異なるクラスインスタンスを操作(override)することができます。

クラスには継承という機能があることを見てきました。

先程の例では、EnemyのプロパティやメソッドをDragonが継承しているので、
Enemyのメソッドの1つであるmove()→print(“Walk forwards.”)も、当然のように継承しています。

しかし、DragonがWalk? おかしくないですか?

このような場合、継承する内容を書き換える(override)ことができます。

それでは、早速、「Walk」を「Fly」に変更してみましょう。

STEP
override(置き換える)
class Dragon: Enemy {   
    override func move() {
        print("Fly forwards")
    }
}
  1. override func move() { ... }:
    Dragon クラス内に存在するメソッドです。
  2. これは Enemy クラスの move() メソッドをオーバーライド(上書き)しています。
    つまり、Dragon クラスでは move() メソッドを独自の内容で上書きしています。
    このオーバーライドは、super.move() などを使って親クラスのメソッドを呼び出すこともできますが、この例では親クラスのメソッドを完全に置き換えています。
let dragon = Dragon()
dragon.move()
//Fly forwards
  1. let dragon = Dragon():
    Dragon クラスのインスタンスを作成しています。
  2. dragon.move():
    Dragon インスタンスの move() メソッドを呼び出しています。
    しかし、この場合は Dragon クラスのオーバーライドされた move() メソッドが呼ばれます
STEP
override(上書きする)

今度は、Enemyのメソッドの1つであるatack()は継承しつつ、
print("Land a hit, does (attackStrengt) damage.")
上書きする(override)方法について、紹介します

class Dragon: Enemy {   
    override func attack() {
        super.attack()
        print("Spits fire, does 10 damage")
    }
}
  • override func attack() { ... }:
    Dragon クラス内に存在するメソッドです。
  • これは Enemy クラスの attack() メソッドをオーバーライド(上書き)しています。

override キーワードは、このメソッドが親クラスのメソッドを上書きしていることを示します。

  1. super.attack() は親クラスの attack() メソッドを呼び出しています。
  2. そして、print("Spits fire, does 10 damage") は新しいメッセージを出力しています。
let dragon = Dragon()

dragon.attack()
//Land a hit, does 10 damage.
//Spits fire, does 10 damage
  1. let dragon = Dragon():
    Dragon クラスのインスタンスを作成しています。
  2. dragon.attack():
    Dragon インスタンスの attack() メソッドを呼び出しています。
    しかし、この場合は Dragon クラスのオーバーライドされた attack() メソッドが呼ばれます。
  3. このメソッド内では、まず親クラスの attack() メソッドが呼び出され、次に「Spits fire, does 10 damage」という新しいメッセージが表示されます。

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次