Skip to content

Swift_class2

kobayashiharuto edited this page Jul 31, 2021 · 9 revisions

クラス

オブジェクト指向と言えば!って感じの存在ですね。
クラスを学んでいきましょう。


クラスとは?

おそらくクラスの概念自体は Swift Playgrounds チュートリアルでやってると思います。
「型」って言われてたやつですね... 「型=クラス」 です。Swift においては完全に一緒です。
型とは設計図であり、それをもとにインスタンスを作ることで動かせるなんて言われていたと思います。
まさに クラスは設計図 です。ではちゃちゃっと復習していきましょう。

さて、「コードを学ぼう2 初期化 違う型のインスタンスを使う」において、以下のように指示を出したのを覚えているのでしょうか?

let character = Character()
let expert = Expert()
 
//expert君への指示
expert.moveForward()
expert.moveForward()
expert.turnLockUp()

//characterちゃんへの指示
character.moveForward()
character.collectGem()
character.moveForward()

// 以下省略 //

これは、Expert というクラスをもとに expert君 いうインスタンスを作り、それを moveForward() などで動かしているということになります。
また、Character というクラスをもとに characterちゃん というインスタンスを作り、それを moveForward() などで動かしているということになります。
これで別々のキャラに指示を出すことが可能になりました。

このような動かし方、まるで実際に存在している物に対してリモコンのように指示を出しているようではないですか?
物...つまりオブジェクトですね。クラスをもとにインスタンスを作ることで、それをオブジェクトのように扱えます。
まるで現実世界のようにオブジェクトで扱えるようにすることで、わかりやすくプログラミングができるのです。

留意点:

コードを学ぼう でも解説されていましたが、クラスはあくまで設計図であり、それをもとに作られたインスタンスをいじることになります
ですので、以下のコードのように同じ設計図でいくらでもキャラクターを作れます

let character1 = Character()
let character2 = Character()
let character3 = Character()
let character4 = Character()

character1.moveForward()

そして、同じ設計図から作られていても、character1 しか動きません。このように、同じ設計図でもインスタンスは別物として扱えるのが、クラスの魅力的な点でしょう。


クラスを見てみよう

コードを学ぼうでは、クラスをインスタンス化してそれを使う、というところはやっていたと思います。
でも、クラスがどう作られているのかが見たことないのでは?

例えば Expert クラスなんかは以下のように実装されているでしょう。

class Expert() {
	
    func turnLock(up: Bool, numberOfTimes: Int) {
        // 鍵を開ける処理 //
    }

    func moveForward(){
        // 歩く処理 //
    }
    
    // 他にもいろんな関数 //
}

このようにで、Expert というクラスの中にそいつが持つ関数を書くことで、いつものように .moveForward() てな感じで使えてたわけです。


クラスを作ってみよう

クラスにメソッド(関数)を持たせよう

それではさっそくクラスを作ってみましょう。
空白のプレイグラウンドを用意してください。(参考:さくっとコードを動かしてみよう

今回は、人を作るクラスを作ってみましょう。
名前は Person クラスとし、greet 関数を実行すると こんにちは と出力されるようにします。

class Person {
    func greet() {
        print("こんにちは")
    }
}

let person = Person()
preson.greet() // こんにちは

こんな感じですね。インスタンスを作成し、greet を実行すると こんにちは という出力が得られると思います。
ちなみに、クラスが持つ関数の事をメソッドと言います。


プロパティ(変数)を持たせよう

さて、せっかくなので名前を持たせて挨拶の時に使いたいですね。
そんな時はクラス内で変数を宣言しましょう。このクラス内の変数をプロパティと言います。

class Person {
    var name = "小林"
    
    func greet() {
        print("こんにちは。私は\(self.name)です。")
    }
}

let person = Person()
preson.greet() // こんにちは。私は小林です。

そういや self とかいう謎のやつがついてますね。これはそのクラス内でクラス内のプロパティやメソッドを使うときにつける必要があるのです。
なぜわざわざこんなルールがあるかは次でわかります。

また、プロパティも同様に、.name というように参照できます。引数が無いので括弧がいりませんね。
これで書き変えや呼び出しが可能になりますね。

let person = Person()
preson.greet() // こんにちは。私は小林です。
print(person.name) // 小林

person.name = "田中"
preson.greet() // こんにちは。私は田中です。
print(person.name) // 田中

インスタンス作成時にプロパティを決めよう(イニシャライザ)

次はインスタンス作成時に名前を決めたいですね。こうすればいろんな名前の人が簡単に作れます。
こういう場合は、init という特殊なメソッドを作りましょう。これは、インスタンス作成時に呼び出されるメソッドです。
ここに引数で名前を渡して、それをプロパティに渡してあげれば、インスタンス作成時に名前を決められますね。
ちなみに、この init メソッドをイニシャライザって言います。(他の言語では大体コンストラクタって呼ばれます)

class Person {
    var name: string
    
    init(name: string) {
        self.name = name // 引数nameの値をnameプロパティに代入!
        print("\(self.name)さんが作成されました。")
    }
    
    func greet() {
        print("こんにちは。私は\(self.name)です。")
    }
}

let person1 = Person(name: '小林') // インスタンス作成時に init への引数を書く
let person2 = Person(name: '田中')
let person3 = Person(name: '佐藤')

preson1.greet() // こんにちは。私は小林です。
preson2.greet() // こんにちは。私は田中です。
preson3.greet() // こんにちは。私は佐藤です。

さあ、わざわざ self を使う理由がわかったでしょうか?それは引数とかの name と クラス内の name を区別するためですね。
こうすることで、同じ命名の変数を使えるのでわかりやすくて便利です。
(例えば VB という言語はこの仕様がないためプロパティと引数を同じ名前にできなくてクソだるいです。わざわざ他の命名をしなきゃいけないので...)


まとめ

クラスを使うと、オブジェクト的に扱えるようになりとても分かりやすくなりますね
せっかくなので、クラスを使っていろいろとコードを書いてみることをおすすめします!
とにかく手を動かすことが習得のコツです

Clone this wiki locally