tetu式

ゲームと音楽・作曲の自己満足と悩みどころの多いプログラムのブログ。

Xcode Swiftのクラス その1:定義と初期化(イニシャライズ)

演算子の話は一回置いといて今回はクラスの話。
これやっとかないと後でいろいろ面倒そうなのでやっちゃいます。




クラスっていうのは簡単に言うと変数やら関数やらを
ひとまとめにしたオブジェクトのことです。


至極単純なプログラムであればクラスを使わなくても
ソースは書いてこれるのですが、
複雑・・・というかモノを扱うようになるとクラスが必要になります。

class animal {
    var name: String = ""
    var foot: Int = 0
    
    func mixPrint() {
        print(name + "は" + String(foot) + "足歩行する")
    }
}

例えば animal というクラスを作ります。
無意識にクラスを作るのではなく、目的を持つことで作りやすくなります。
名前と何足歩行かを指定し、mixPrintを呼び出すと「◯◯は△足歩行する」
という文章を出力します。

var human = animal()
human.name = "ヒト"
human.foot = 2
human.mixPrint()

var cat = animal()
cat.name = "ネコ"
cat.foot = 4
cat.mixPrint()

宣言は変数を入れる代わりに クラス名() を入れます。
こういう場合はインスタンス生成なんて言ったりします。


その後は インスタンス名.クラス内で用意した変数や関数 で
クラスの内容を利用することができます。


クラスの利用の注意点としてクラス内で使われている変数は
参照渡しであるという点があります。

var a = 5
var b = a
b = 7

print(a)  // 5
print(b)  // 7

通常の変数は値渡しと呼ばれる渡し方をしており、
代入時に別な変数を入れるとその変数の値を渡します。
渡した時点で b は 5 ですが、その後に 7 が入ります。
その直後に a と b をそれぞれ出力すると 5 と 7 が出力されます。


このように代入時に中身だけ渡してもそれぞれ別々に領域を持った
渡し方を値渡しと言います。

var human = animal()
var man = human
man.name = "男性"
man.foot = 2

var woman = human
woman.name = "女性"
woman.foot = 2

man.mixPrint()  // 女性は2足歩行する
woman.mixPrint()  // 女性は2足歩行する


参照渡しというのは領域のアドレスを渡す手法になります。
一見 man と women は別々のものに見えますが、
同じ human というアドレスを持つようになるため、
後に書かれたコードで変数を上書きするようになります。


パソコンの操作で置き換えてみましょう。
まずanimalというフォルダにname.txt、foot.txt、mixPrint.exeがあると思ってください。
animalフォルダをコピーし、humanというフォルダ名にします


次にmanという名前でhumanへのショートカットを作り、
name.txtに男性、foot.txtに2と入れます。


その後、womanという名前でhumanへのショートカットを作り、
name.txtに女性、foot.txtに2と入れます。


ショートカットの参照先はどちらも human になるため、
同じファイルを編集しているということになります。

今回のソースコードを置き換えると大体こんなイメージです。


あとインスタンス生成時の初期化(イニシャライズ)についても触れておきましょう。

class animal {
    var name: String = ""
    var foot: Int = 0
    
    init (_ fName: String, _ fFoot: Int) {
        name = fName
        foot = fFoot
    }
    
    func mixPrint() {
        print(name + "は" + String(foot) + "足歩行する")
    }
}

var human = animal("人", 2)

human.mixPrint()


クラス内に init() を作成することでインスタンス生成時の処理を
入れておくことができます。
カッコ内には引数を用意しておくこともできます。


今回はインスタンス生成と同時にnameに人、footに2が
入るようになっています。
毎回クラス内変数に直接アクセスして値を設定するのは結構行数が
増えたりするものなので、こういう処理は大事です。



今回はここまで。