顯示具有 程式-SWIFT 標籤的文章。 顯示所有文章
顯示具有 程式-SWIFT 標籤的文章。 顯示所有文章

2016年6月15日 星期三

SWIFT-多型(polymorphism),Protocol, 整合範例練習

Protocol: 用於定義方法和屬性的名稱藍圖,而不提供實作任何功能。(像契約)

整合範例練習重點:
1. 評估Enum , Struct , Class 使用時機.
2. 練習Protocol & 多型(polymorphism)實作.
3. 練習Class繼承
4. 根據輸入條件(半徑, 長寬, 正方形寬), 計算面積 / 周長

 物件類別圖 - 協助定義相互關係

types.swift 

main.swift & Result 執行結果


[Code程式區 - types.swift]
protocol  ShapeDelegate {
    var area : Double {get}
    var peremeter : Double {get}
    func showInfo()
}

struct Circle : ShapeDelegate {
    var radius : Double
    // Protocol 所定亦需要的實作
    var area : Double {
        // 面積
        return M_PI*pow(radius, 2.0)
    }
    var peremeter : Double {
        // 周長
        return M_PI*radius*2.0
    }
    func showInfo(){
        print("\(self.dynamicType) : \nArea : \(area)\nPeremeter : \(peremeter)")
    }
}

// Global Function
func showShapeInfo(shape : ShapeDelegate){
    print("\(shape.dynamicType) : \nArea : \(shape.area)\nPeremeter : \(shape.peremeter)\n")
}

class Rectangle : ShapeDelegate {
    var width : Double
    var height : Double
    init(width : Double, height : Double){
        self.width = width
        self.height = height
    }
    // Protocol 所定亦需要的實作
    var area : Double {
        return width * height
    }
    var peremeter : Double {
        return (width + height)*2.0
    }
    func showInfo(){
        print("\(self.dynamicType) : \nArea : \(area)\nPeremeter : \(peremeter)")
    }
}

class Square : Rectangle{
    init(width : Double){
        super.init(width: width, height: width)
    }

}


[Code程式區 - main.swift]
let c1 : ShapeDelegate = Circle(radius: 10)
c1.showInfo()
let r1 : ShapeDelegate = Rectangle(width: 6, height: 8)
r1.showInfo()
let s1 : Rectangle = Square(width: 7)
s1.showInfo()
showShapeInfo(c1)
showShapeInfo(r1)

showShapeInfo(s1)


George Huang 烤蕃薯@Taipei 2016

SWIFT-多型(polymorphism)範例練習

透過此 多型(polymorphism)範例練習,來練習如何輕鬆達成薪資系統的三件事-實作範例。
1. 計算每個員工獎金紅利判定方法.
2. 計算每個員工需要繳的稅金利率.
3. 如何透過異質集合(Checking Thype) 來輕鬆計算所有員工的薪資總和. 

Swift 實作
types.swift

main.swift

[Code程式區 - types.swift]
// 計算員工拿獎金
func getBouns(e : Employee) {
    // 特例處理, 子孫類別先判對, 順序很重要
    if e is Manager{
        print("+1000")
        let m1 : Manager = e as! Manager
        print(m1.dept ?? "?")
    } else if e is Employee {
        print("+500")
    }
}

// 計算員工需要繳的稅
func getTax(e : Employee) {
    let totalY = e.salary * 14
    if totalY < 800_000 {
        print("Your tax is : 5%")
    } else {
        print("Your tax is : 12%")
    }
}

class Employee {
    var name : String?
    var address : String?
    var salary : Int = 20000    // 假設底薪28000-
    func showInfo() {
        print("\(name ?? "Noname") lives in \(address ?? "somewhere")")
    }
}

class Manager: Employee {
    var dept : String?
    override func showInfo() {
        print("\(name ?? "Noname") a manager of \(dept ?? "???"), Lives in \(address ?? "somewhere")")
    }
}

class Engineer : Employee{
    

}

[Code程式區 - main.swift]
var m1 = Manager()
m1.name = "George"
m1.address = "Taipei"
m1.dept = "Engineer" // 繼承後, 客製化增加的
m1.salary = 60000
m1.showInfo()

// SWIFT-多型(polymorphism)範例測試, (Protocol 也會再一次碰到.)
var e : Employee = Manager()
e.name = "Frank"
e.address = "Tainan"
let m2 = e as? Manager  // 將e轉化它的型別成為Manager
m2?.dept = "IT2"
e.showInfo()    // 此時是呼叫執行實體Manager.showInfo()

var e1 : Employee = Employee()
e.name = "Frank"
e.address = "Tainan"
e.showInfo()    // 此時是呼叫執行實體Manager.showInfo()

var e2 : Employee = Employee()
e.name = "Sam"
e.address = "Tainan"
e.showInfo()    // 此時是呼叫執行實體Manager.showInfo()

var e3 : Engineer = Engineer()
e3.name = "George"
e3.address = "Taipei"
e3.showInfo()

// 多型應用-異質集合(Checking Thype) (抓出共通性來進行運作)
var employee : [Employee] = [m1, e1, e2, e3]
var total = 0
for e in employee {
    total += e.salary
}
print("TOT: \(total)")

getTax(m1)
getTax(e1)

getTax(e2)


George Huang 烤蕃薯@Taipei 2016

SWIFT-擴充型別Extension & Protocol 練習

Protocol: 用於定義方法和屬性的名稱藍圖,而不提供實作任何功能。(像契約)

Swift 實作
types.swift



main.swift


[Code程式區 - types.swift]
// Protocol 練習
@objc protocol Adelegate {
    func m1()
    optional func m3()
}

protocol  BDelegate {
    func  m2()
    var demo : Int {get set}
}

// Protocol多重繼承
protocol  CDelegate: Adelegate, BDelegate {
    func  m3()
}

// 宣告使用Protocol 就必須要實作
class A : Adelegate, BDelegate{
    @objc func m1() {
        print("print m1")
    }
    func m2() {
        print("print m2")
    }
    var demo: Int {
        get{
            return 12
        }
        set{
            
        }
    }
}

extension NSDate{
    convenience init(dateString:String) {
        let formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        let date : NSDate? = formatter.dateFromString(dateString)
        self.init(timeInterval : 0, sinceDate: date ?? NSDate())
    }
    
    var year : Int{
        let formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy"
        let str = formatter.stringFromDate(self)
        return Int(str)!
    }
    
    var month : Int{
        let formatter = NSDateFormatter()
        formatter.dateFormat = "MM"
        let str = formatter.stringFromDate(self)
        return Int(str)!
    }
    
    var day : Int{
        let formatter = NSDateFormatter()
        formatter.dateFormat = "dd"
        let str = formatter.stringFromDate(self)
        return Int(str)!
    }
    
    func showInfo() {
        print("Date : \(year) /\(month)/\(day)")
    }

}


[Code程式區 - main.swift]
// 練習擴充型別 Extension
let date = NSDate(dateString:"2010-10-10")
date.showInfo()

// 練習單一Prorocol
var v1 : Adelegate = A()
var v2 : BDelegate = A()
v1.m1()
v2.m2()

// 練習protocol多筆合成

let v3 : protocol<Adelegate, BDelegate> = A()



George Huang 烤蕃薯@Taipei 2016

SWIFT物件規劃 & 實作範例 - 終極密碼

終極密碼-遊戲規劃 & 實作
[需求]
1.
程式會亂數產 個介於 1 ~ 100的數值作為答案
2. 玩家所輸 數字如果就是答案,程式會終 並輸出輸 次數與答案。 3. 玩家必須玩到猜對為 。
4. 玩家所輸 數字如果不是答案,程式會提 範圍(Message Prompt)。
Ex: Answer = 51
User entered Message Prompt

1st : 33 34 ~ 100 2nd : 75 34 ~ 74

[領域分析]Domain Analysis
1.
程式會亂數產 個介於 1 ~ 100的數值作為答案
int answer;
2.
玩家所輸 數字如果就是答案,程式會終 並輸出輸 次數與答案。
String inputStr; int count; 3. 玩家必須玩到猜對為 。
4. 玩家所輸 數字如果不是答案,程式會提 範圍(Message Prompt)。
ex Answer = 51
User entered Message Prompt

1st : 33
2nd : 75 3rd : 79
34 ~ 100
int lowerbound; int upperBound ;

34 ~ 74 34 ~ 74

[流程分析] //產 亂數做為解答 //提 訊息含上下邊界 //讀取玩家輸
//轉型 & count++ // 對成功,輸出次數與解答 // 對失敗,調整上下邊界

[類別分析]
  1. //產 亂數做為解答(GameData)
  2. //提 訊息含上下邊界(GameFlow)
  3. //讀取玩家輸 (GameFlow)
  4. //轉型 & count++(GameData)
  5. // 對成功(GameData),輸出次數與解答(GameFlow)
  6. // 對失敗,調整上下邊界(GameData)
[類別設計]:功能導向
1. 資料處理(GameData):

2. 流程處理:
    ● 初始化邏輯(GameData)
    寫在建構函式中
    ● 對流程(compare Method, GameData):
    public bool compare(String inputStr)
    //次數加1    //String --> int (casting error return false)    //compare to answer    //if true, return true    //if false, update lowerBound or upperBound, and return false
    ● 遊戲主流程(GameFlow): //產 遊戲資料
    //提 訊息含上下邊界
    //讀取玩家輸 Call GameData’s compare Method
    // 對成功,輸出次數與解答 // 對失敗,遊戲繼續執  


Swift 實作
types.swift
 main.swift



[Code程式區 - types.swift]

class GameData{
    //1: 屬性宣告
    var answer : Int
    var count : Int
    var upperBound : Int
    var lowerBound : Int
    
    init(){
        //2: 變數初始化
        count = 0
        upperBound = 100
        lowerBound = 1
        //產生亂數做為解答
        answer = Int(arc4random()) % (upperBound - lowerBound + 1)  + lowerBound
    }
    
    // 3. 比對邏輯
    func compare(userInputStr: NSString)->Bool{
        //轉型 & count++
        count += 1
        let userInput = userInputStr.integerValue
        if answer == userInput{
            //比對成功,輸出次數與解答
            //print("ANSWER: \(answer), COUNT : \(count).")
            //break
            return true
        }else{
            //比對失敗,調整上下邊界
            if userInput < answer && userInput >= lowerBound {
                lowerBound = userInput + 1
            }else if userInput > answer && userInput <= upperBound{
                upperBound = userInput - 1
            }
        }
        return false
    }
}


struct  GameFlow {
    // 4: 屬性宣告
    var data = GameData()
    
    // 5: 讀取使用者輸入
    func getInput() -> NSString {
        let keyboard = NSFileHandle.fileHandleWithStandardInput()
        let inputData = keyboard.availableData
        return NSString(data: inputData, encoding:NSUTF8StringEncoding)!
    }
    
    // 6: 主要流程
    func play(){
        while true{
            //提示訊息含上下邊界
            print("OO Please enter a number between \(data.lowerBound) ~ \(data.upperBound):")
            //讀取玩家輸入
            let userInputStr = getInput()
            if data.compare(userInputStr){
                // 比對成功, 輸出次數與解答
                print("OO Answer: \(data.answer), Count: \(data.count).")
                break
            }
            
        }
    }

}

[Code程式區 - main.swift]

// 7:程式執行
let game = GameFlow()
game.play()




George Huang 烤蕃薯@Taipei 2016


2016年6月11日 星期六

SWIFT-Protocol與Delegate




Reference: 
電腦人-SWIFT自學力!圖解140個iOSAPP開發範例給新手的超直覺設計指南
範例下載-Github https://github.com/WEI-WEI-SWIFT/iOS-Swift-Cookbook-2AU040


//********************************************************************
//********************************************************************
//********************** Protocol and Delegate ***********************
//********************************************************************
//********************************************************************

protocol BossDelegate{
    func makeMoneyForBoss()
}

class Employee:BossDelegate{
    func makeMoneyForBoss() {
        print("水喔$$$$$")
    }
}

class Boss{
    var delegate:BossDelegate?
    func gonnaMakeMoney(){
        delegate?.makeMoneyForBoss()
    }
}

let aBoss = Boss()
let aEmployee = Employee()
aBoss.delegate = aEmployee

aBoss.gonnaMakeMoney()