[Swift] クラス、プロトコルの宣言

クラス宣言はとてもシンプル

class クラス名:基底クラス {
	
	・・・実装

}

やっぱり構文はシンプルなのが一番

 
いろんな要素を詰め込んだクラスのサンプル


class Programmer {
    
    // プロパティの宣言
    // 普通に宣言
    var name = ""
    // ※今のところprivateな宣言は出来ないっぽい
    

    // セッター、ゲッターの指定
    var _company:String?
    var company:String? {
      get {
        return _company
      }
      set(newValue){
        _company = newValue
      }
    }
    //※ セッター、ゲッターの指定は他のプロパティから計算で求められたり、
    //  計算結果を他のプロパティに格納するような場合に使うと良いと思う。
    //  この例は良くないね。

    
    // 遅延評価するプロパティ
    // ※最初に参照された時に初期化される
    @lazy var skills = Array<String>()
    
    
    // ReadOnlyなプロパティ
    var displayName:String {
    	if let cmp = company {
        	return "\(name)@\(cmp)"
    	} else {
        	return "\(name)"
        }
    }

    
    // プロパティオブザーバー
    // プロパティの値が変更する前後に処理を行う
    var experienceYears:Int = 0 {
    	
    	// willSetではプロパティに値が設定される直前に処理を行うことができる
    	willSet(newValue){
        	NSLog("経験年数が\(experienceYears)から\(newValue)に変更されようとしています。")
    	}

    	// didSetでは値が登録された後に処理を行うことができる
    	didSet {
        	//didSetでは変更前の値が oldValue として参照できる
        	NSLog("経験年数が\(oldValue)から\(experienceYears)に変更されました!")
        	if (experienceYears > 100){
            	// 値を再設定することも出来る
            	NSLog("でも何かの間違いなので元に戻します。")
            	experienceYears = oldValue
        	}
    	}
    }
    


    // subscript
    // C#のインデクサ的なもの    
    subscript(index:Int) -> String {
        get{
            return skills[index]
        }
        set(newValue){
            if skills.count <= index {
                skills += Array(count:index - skills.count + 1,repeatedValue:"")
            }
            skills[index] = newValue
        }
    }
    // ※ subscript(row: Int, column: Int) のように複数のパラメータを受けるように宣言することも可能

    
    
    // タイププロパティ(Type - Property)
    // クラス変数、スタティックプロパティのように理解すればよいか?
    // ※ まだ対応されていないようです
    // class var dislike = "I hate Change Request!!"
    
    

    // イニシャライザの定義
    init(name:String){
        self.name = name
    }
    
    // コンビニエンス イニシャライザ
    convenience init(){
        // 自身のinitを呼び出す必要がある
        self.init(name:"(匿名)")
    }
    
    // デイニシャライザ(?)
    // デストラクタ的なやつ
    deinit {
        // ・・・リソースの開放を行う
    }
    


    // メソッドの定義
    // 普通ですね
    func skillCaption() -> String {
        var result = ""
        for skill in skills {
            result += " \(skill)"
        }
        return result
    }
    
    
    func program(){
        NSLog("やってもやっても終わらない!")
    }
    
}

 
このクラスprogrammerを継承


class SwiftProgrammer:Programmer{

    // initではsuperのinitを呼び出さないとエラーとなる
    init(name:String){
        super.init(name:name)

        skills.append("swift")
    }
    

    // オーバーライド
    override func program(){
        NSLog("Swiftだと仕事が早い!不思議!")
    }
    

    // プロパティのオーバーライド
    override var company:String? {
    	get {
        	return "SwiftCompany-" + (_company ? _company! : "")
    	}
    	set(newValue){
        	super.company = newValue
    	}
    }
}

  

 
プロトコル
もうobjective-cとか気にせずにインターフェースって呼べばいいのにね。


// プロトコルの宣言
protocol Agiler {
    
    // プロパティの宣言
    var canRefactoring:Bool { get set }
    
    // メソッドの定義
    func scrum() -> String
    
}

// プロトコルの実装
class AgileProgrammer:Programmer,Agiler{
    
    init(name:String){
        canRefactoring = false
        super.init(name:name)
    }
    
    
    // protocol[Agiler]の実装
    
    var canRefactoring:Bool
    
    func scrum() -> String {
        return "スクラム"
    }
    
}

 

クラスのインスタンスを生成するときはnewとか不要



    let programmerA = Programmer()
    programmerA.company = "りんごコンピュータ"
    programmerA.experienceYears  = 5
    programmerA.experienceYears  = 200
    programmerA[0] = "swift"
    programmerA[1] = "objective-c"
    
    NSLog("A displayName:\(programmerA.displayName) skills:\(programmerA.skillCaption()) career:\(programmerA.experienceYears)")
    
    
    // コンビニエンスイニシャライザを使ってインスタンス化
    let programmerB = Programmer(name:"まさお")
    NSLog("B displayName:\(programmerB.displayName)")
    
    // 継承されたクラスをインスタンス化
    let programmerC = SwiftProgrammer(name:"ひろし")
    programmerC.company = "ゴーグル"
    NSLog("C displayName:\(programmerC.displayName)")

インスタンスのメモリはARCによって管理されるので明示的な廃棄処理は不要です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です