Skip to content

Instantly share code, notes, and snippets.

@SatoTakeshiX
Created February 17, 2016 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SatoTakeshiX/a6aa752a83f542e8df3d to your computer and use it in GitHub Desktop.
Save SatoTakeshiX/a6aa752a83f542e8df3d to your computer and use it in GitHub Desktop.
【朝活】iOS開発会議 in beez渋谷50回目 サンプルコード
//: Playground - noun: a place where people can play
import UIKit
/*
プロトコル:実装を伴わない宣言の集合。インターフェース。クラス、構造体、列挙型を定義するとき、プロトコルを指定して、そのプロトコルが宣言しているメソッドなどを宣言。継承できない構造体でも、プロトコルに定義されているインターフェースの実装が保証される。
「用語」
プロトコルを採用する->プロトコルを使ってクラス、構造体、列挙型を定義する
プロトコルに適合する。プロトコルに準拠する->プロコトルを採用したクラス、構造体、列挙型
Swiftでプロトコルで宣言できるもの
・インスタンスメソッド、タイプメソッド
・関数宣言
・インスタンスプロパティ、タイププロパティ
・イニシャライザ
・添字付け
・typealias宣言
*/
/*
プロトコルの文法
*/
//ネズミっぽい食べ方ができるプロトコル
protocol MouseEatable{
//インスタンスプロパティは var <プロパティ名> : 型 { get set }
//setterを強制させるプロパティ
var cheekpouch : Int { get set }//ほおぶくろ
//{get}のみは実装時にsetterをつけてもよい。つけなくてもよい
var tooth : Int { get } //歯の数
//メソッドは func <メソッド名> (引数 : 引数の型 ) -> 返り値の型
//自分のプロパティを操作するならmutatingをつける
mutating func storeFood (number : Int) ->Int//ほおぶくろに食べ物をいれる
}
//動物の生活形式
protocol FormOfLife{
//タイププロパティは staticをつける
//staticなら構造体、列挙型、クラスどれでもタイプメソッドがつくれる
static var isNocturnality : Bool { get } //夜行性かどうか
var myName : String { get }//自分の名前
//初期化も宣言できる
init(name : String)
}
//クラスのみのプロトコルは classをつける
protocol OnlyClassProtocol : class {
//クラスのタイププロパティもstatic
static func typeClassMethod()
}
//プロトコルを採用。複数採用するときはカンマ(,)で指定する
struct Hamster : MouseEatable, FormOfLife {
let myName : String
//プロトコル宣言ではget setなのでletではなくvarで実装しなければいけない
var cheekpouch = 10 //どんぐりを10個入れれるほうぶくろ
//get なので letでも実装できる。varでも実装できる。プロトコルでgetで宣言されたものは実装するときはgetter,setterどちらも実装できるようにしてもよい。
let tooth = 16 //歯は16本。
//夜行性
static let isNocturnality : Bool = true
//ほおぶろくに入れるメソッド
mutating func storeFood(number : Int) -> Int {
self.cheekpouch = self.cheekpouch + number
return self.cheekpouch
}
//初期化メソッド
init(name: String) {
myName = name
}
}
//クラスでもプロトコルを採用する
// class <クラス名> : superClass , Protocol1, Protocol2{}
class Cat : FormOfLife {
static let isNocturnality = false//夜行性ではない
let myName : String//自分の名前
//プロトコルの初期化メソッドはクラスの時はrequiredをつける
required init(name: String) {
myName = name
}
}
/*
プロトコルを型として使う
*/
var hamham = Hamster(name: "ハムハム")//構造体
var mike = Cat(name: "ミケ")//クラス
//プロトコルが同じなら型指定して配列に入れられる
let petList : [FormOfLife] = [hamham, mike]
//同じプロトコルが指定されているので、プロパティを同じように利用できる
for pet in petList{
//ペットの名前を確認
print(pet.myName)
}
/*
プロトコルの継承
プロトコルを宣言するときに、別のプロトコルを継承することができる。新しく宣言したプロトコルは継承先のプロトコルの内容を引き継ぐ
*/
//ハムスターの食べ方ができるプロトコルHamsterEatableをMouseEatableを継承して作成する
protocol HamsterEatable : MouseEatable{
//ひまわりのタネ
var sunflowerSeed : Int { get set}
}
//継承したプロトコルを採用する
class Djungarian : HamsterEatable {
//継承先(HamsterEatable)のプロパティ
var sunflowerSeed = 10
//継承元(MouseEatable)のプロトコル
var cheekpouch = 0
var tooth = 0
func storeFood (number : Int) ->Int{
return number
}
}
//インスタンスを作る
let djungarian = Djungarian()
/*
プロトコルが適合するかをチェックする
is
式 is someprotocol
式がプロトコルに適合したらtrue、そうでないならfalse
as?
式 as? someprotocol
式が型としてのプロトコルのオプショナルにダウンキャストされる。式がプロコトルに適合していなかったらnilを返す
as!
式 as! someprotocol
式が型としてのプロトコルにダウンキャストされる。式がプロトコルに適合していなかったら実行時エラー
*/
//プロトコルを採用していないクラスを作る
class Rock {
let width : Int = 0
let height : Int = 0
let length : Int = 0
}
//インスタンスを作る
let rock = Rock()
//AnyObjectで配列を作る
let list : [AnyObject] = [djungarian, rock]
//プロコトルを採用しているかをループで回して確認する
for object in list{
//as?でプロトコルを採用しているかどうかをみる
if let object = object as? HamsterEatable {
print("\(object)はひまわりの種は \(object.sunflowerSeed)個ある")
} else {
print("\(object)はひまわりの種はもってない")
}
// isはプロトコルを採用していればtrueを返す。していなければfalseを返す
if object is HamsterEatable{
print("\(object)はひまわりの種を持っている")
}
}
//プロコトルの合成
//複数のプロコトルの型指定をする事ができる
//変数: protocol<protocol1, protocol2>
//職業プロトコル
protocol Job {
var jobName : String { get set }
}
//住所プロコトル
protocol Adress {
var adressName : String { get set }
}
struct Person :Job, Adress {
var jobName = "エンジニア"
var adressName = "東京"
}
//プロコトルJobとAdressをどちらも採用している変数を引数にする関数を作る
func Identification (person : protocol<Job, Adress>) -> String{
return "あなたの職業は\(person.jobName)で、お住いは\(person.adressName)です"
}
let sato = Person()
print(Identification(sato))
//デリゲートパターン
//->プロジェクトでつくる
//プロトコルの拡張でデフォルトの実装を作る!
//Swift2からの追加機能
//鳴き声のプロトコル
protocol Criable {
//どんな鳴き声で泣くのか
var cryString : String { get }
//叫び声
var roarString : String { get }
//実際に泣くメソッド
func cry() -> String
}
//extensionでプロパティ、メソッドのデフォルト実装を作ることができる
extension Criable {
//鳴き声メソッド
//鳴き声を2回繰り返す
func cry() -> String {
return cryString + cryString
}
//叫び声はデフォルトを作る
//ストアドプロパティは作れない。
var roarString : String {
return "ガオー"
}
}
//猿の構造体
struct Monkey : Criable {
let cryString : String
//プロトコル拡張で実装したものは構造体宣言時に改めて実装してもよいみたい
//let roarString : String = "うが~"
//func cry() -> String {
// return cryString + cryString + cryString
//}
}
//ゴリラを作る
let gorilla = Monkey(cryString: "ウホ")
print(gorilla.cry())
print(gorilla.roarString)
//チンパンジーを作る
let chimpanzee = Monkey(cryString: "ウッキー")
print(chimpanzee.cry())
//既存のプロトコルを拡張する。
//Array型に採用されているCollectionTypeというプロトコルを拡張する。
extension CollectionType where Generator.Element :Criable{
var cryString : String{
//各要素の鳴き声
let crysAsText = self.map{ $0.cry()}
return "[" + crysAsText.joinWithSeparator(", ") + "]"
}
}
let monkeys = [gorilla, chimpanzee]
//Array型の変数にcryStringを追加できた!!
print(monkeys.cryString)
/*
参考資料
http://tea-leaves.jp/swift/content/%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB
Swift : クラス継承とプロトコル拡張を比べてみる #yidev
http://www.slideshare.net/tomohirokumagai54/swift-yidev
http://tea-leaves.jp/swift/content/%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB
->ちょっと古い??
WWDC
https://developer.apple.com/videos/play/wwdc2015-408/
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment