Swiftにはクラス(Class)と構造体(struct)が存在します。

どちらもプロパティやイニシャライザ、メソッドを定義することできるのでよく似ていますが、クラスは参照型で代入した場合オブジェクトの中身はコピーされないのに対し、構造体は値型で代入すると値のコピーが発生するところが大きくことなります。

クラスの基本

Swiftのクラス定義は以下のようになります。

プロパティはイニシャライザ等を利用して初期化する必要があります。

class Person {
    var name: String
    var age: Int
    
    //イニシャライザ
    init(name:String = "Unknown", age:Int = 17) {
        self.name = name
        self.age = age
    }
    
    func description() -> String {
        return "age=\(age) name=\(name)"
    }
}

オブジェクトを生成してほかの変数に代入。変数が同じオブジェクトを参照しているかどうかは「===」を利用して比較します。

//オブジェクトの生成
var person = Person()
person.description()
// オブジェクトを代入した場合: 同じオブジェクトを指す
var person2 = person
// オブジェクトが同じかどうかを調べる場合"==="を使う
if person === person2 {
    //同じオブジェクトを参照している
    print("同じオブジェクトです")
} else {
    print("異なるオブジェクトです")
}

personとperson2は同じオブジェクトを参照しているため、personのプロパティの値を変更するとperson2のプロパティの値も変わっていることが分かります。

// 名前を変更
person.name = "匿名希望"
if person2.name == "匿名希望" {
    // 同じオブジェクトを参照しているperson2.nameも変わっている。
    print("名前が変わりました")
} else {
    print("名前は変わりません")
}

2つのオブジェクトを生成して比較すると同じ値でも異なるオブジェクトと判定されます。

// 別のオブジェクトを生成
var person3 = Person()
var person4 = Person()
if person3 === person4 {
    print("同じオブジェクトです")
} else {
    //異なるオブジェクトを参照している
    print("異なるオブジェクトです")
}

構造体の基本

構造体の定義は以下のようになります。

struct Size {
    var height: Int
    var width: Int
    func description() -> String {
        return "height=\(height) width=\(width)"
    }
}

構造体を代入すると値がコピーされます。

//構造体では自動的にイニシャライザが作られます
var size = Size(height: 100, width: 200)
size.description()

var size2 = size
if size2.height == size.height && size2.width == size.width {
    print("同じ値ですです")
} else {
    print("異なるsじ値ですです")
}

static変数とstaticメソッド

クラス毎に定義される静的変数や静的メソッドを定義するにはstaticキーワードやclassキーワードが使えます。classキーワードを使うとサブクラスでメソッドをオーバーライドすることができます。

静的変数やメソッドはオーバーライドできないという流儀になれている方は、staticを使うと良いかもしれません。

//static変数とstaticメソッド
class PersonEx {
    static var totalCount: Int = 20
    
    static func printTotalCount() {
        print("printTotalCount=\(totalCount)")
    }
    
    var name: String
    var age: Int
    
    //イニシャライザ
    init(name:String = "Unknown", age:Int = 17) {
        self.name = name
        self.age = age
    }
    
    func description() -> String {
        return "age=\(age) name=\(name) totalCount=\(PersonEx.totalCount)"
    }
}

PersonEx.printTotalCount() //=>"printTotalCount=20\n"

let personex = PersonEx(name:"鈴木一郎", age:30)
personex.description() //=>"age=30 name=鈴木一郎 totalCount=20"