Swift/protocol
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[Swift]]
*Swift/プロトコル [#d3274344]
オブジェクト指向言語の継承の概念は、クラス継承とインター...
インターフェイス継承をSwiftはプロトコルと呼ぶ。
プロトコル (protocol) は実装を伴わない宣言の集合である。
クラス、構造体、列挙型などを定義するときにプロトコルを指...
そのプロトコルが宣言しているメソッドを実装する。
これにより継承関係のない型でも、プロトコルで宣言された同...
public protocol CustomStringConvertible {
public var description: String { get }
}
プロトコルを使ってクラス(や構造体や列挙型など)を定義する...
「プロトコルを採用 (adopt) する」といい、そのクラス(や構...
「プロトコルに適合 (conform) している」という。
Swiftでプロトコルに含めることができるのは、次の宣言である。
-インスタンスメソッド、タイプメソッド
-演算子による関数の宣言
-インスタンスプロパティ、タイププロパティ
-イニシャライザ
-添字付け
-typealias宣言
プロトコル名は大文字開始のキャメルネームにする。
プロトコルは他のプロトコルを継承することができる。
// { }内はいずれもオプションで順番や個数に制限はない
// [ ]の部分はさらに省略可能
protocol プロトコル名 : プロトコル列 {
[static] func メソッド名 ([仮引数]) [-> 型]
[prefix | postfix] func 演算し ([仮引数]) [->型]
[static] var プロパティ名 : 型 { get [set] }
init([仮引数])
subscript(仮引数) -> 型 { get [set] }
typealias 型名 [= 型]
}
プロトコル Person の例
protocol Personal {
var name: String { get }
init(name: String)
func sayHelloTo(p: Personal)
func saySomething() -> String
}
***メソッドの宣言と定義 [#dc6f0da1]
プロトコルでのメソッドの宣言は、コードブロックは記述しな...
(プロトコルの拡張定義ではコードを記述して、プロトコルのデ...
タイプメソッドを定義するときは static 修飾子を記述する。
***プロパティの宣言と定義 [#p5b24355]
プロパティが読み書き可能の場合はsetとgetを、読み出し専用...
読み出し専用プロパティでも、プロトコルでは var と宣言する...
プロトコルで 読み出し専用として宣言したプロパティを、実装...
実装が格納型か計算型かはプロトコル側では記述しない。
***イニシャライザの宣言と定義 [#lab8ea0c]
イニシャライザを指定することもできる。クラスの必須イニシ...
クラスの実装では required キーワードをつける必要があり、
そのクラスを継承したサブクラスでも同じイニシャライザを定...
(ただし、クラス定義でfinalを指定している場合は、もうサブ...
required を記述する必要はない。)
designated initializer か convenience initalizer の区別は...
class Citizen : Personal {
let name: String // プロトコルを定数で実装する
required init(name: String) { // required が必要
self.name = name
}
func sayHelloTo(p: Personal) {
print("\(p.name)さん、こんにちは")
}
func saySomething() -> String { return "なるほど" }
}
***クラス定義のためのプロトコル [#eaa58848]
クラス(参照型)での実装だけを想定してプロトコルを定義する...
そのような場合は、クラスだけが対象であることを明示するた...
class キーワードを置く。
protocol TripleTappable : class { // 以下、略
protocol Nerberality : class, 別のプロトコル { // 以下、略
クラス限定のプロトコルの場合、メソッドに mutating という...
**プロトコルと型 [#he33aac4]
プロトコルは型として使うことができる。
func printNames(list: [Personal]) {
for p in list {
print(p.name + ": " + p.saySomething())
}
}
typealias による付属型の指定や Self を使って宣言されたプ...
***プロトコルの継承 [#e01f5a1a]
enum Sex { cse Male, Female } // 性別を表す列挙型
protocol HealthInfo : Personal { // プロトコルを継承する
var weight: Double { get set } // 読み書き可能なプロ...
var height: Double { get set }
var sex: Sex? { get } // read onlyなプロパティ
}
***プロトコルの合成 [#bcdaaa51]
複数のプロトコルのUnionのプロトコルを作成できる。
次の例では、NewProtocolという新しいプロトコルを定義し...
一時的に使いたいだけならば protocol<> という記述もできる。
protocol NewProtocol : プロトコル1, プロトコル2 {}
var teller: NewProtocol
または
protocol<プロトコル1, プロトコル2> teller
***プロトコルへの適合を調べる [#c43b7ed4]
Pをプロトコル, 式を exp とする。
- exp is P --- 式 exp がプロトコル P に適合したインスタン...
- exp as P --- 式 exp がプロトコル P にキャストされる。適...
- exp as? P --- 式 exp がプロトコル P のオプショナル型に...
- exp as! P --- 式 exp がプロトコル P のオプショナル型に...
**プロトコルと付属型 [#c9aec7a7]
***ネスト型とプロトコル [#o8cbd247]
次の例では、Elementの定義がなく、プロパティxとyがElement...
protocol VectorType { // 2次元ベクトル型
typealias Element // 付属型の宣言
var x : Element { get set }
var y : Element { get set }
}
プロトコル内で typealias を使って定義される付属型はジェネ...
型の定義にプロトコルが採用されたときその型で実際に使われ...
型パラメータや付属型はコンパイル時に静的に解析される。
struct VectorFloat : VectorType {
var x, y: Float // 付属型に具体的な型を指定した
func onvToDouble() -> VectorDouble {
return VectorDouble(
x: VectorDouble.Element(x), // 型として利用
y: VectorDouble.Element(y)
)
}
}
struct VectorDouble : VectorType, CustomStringConvertibl...
var x, y: Double // 付属型に具体的な型を指定した
var description: String { return "[\(x), \(y)]" }
}
struct VectorGrade : VectorType {
enum Element { case A, B, C, D, X } // ネスト型を定...
var x, y: Element
}
var a = VectorFloat(x: 10.0, y: 12.0)
let b = a.convToDouble()
print(b) // [10.0, 12.0] と表示される
***付属型が適合するプロトコルを指定する [#y315c4f2]
プロトコルを採用した型で動作する共通のメソッドを宣言しよ...
付属型で表される型にどのような操作や演算が可能かを指定で...
そのためには適合するパラメータを指定すればよい。
protocol VectorIntegerType {
typealias Element: IntegerType // 付属型に適合する...
var x : Element { get set }
var y : Element { get set }
}
struct VectorInt: VectorIntegerType {
var x, y: Int
mutating func add(x:Int, y:Int) {
self.x += x; self.y += y
}
}
struct VectorUInt16: VectorIntegerType {
var x, y: UInt16
}
let mx: VectorInt.Element = 10 // VectorInt.ElementはI...
var a = VectorInt(x:mx, y:-7)
a.add(x:10, y:9) // (x: 20, y: 2) になる。
*プロトコルに適合する型の定義方法 [#i4af640c]
プロトコル Equatable と Comparable
終了行:
[[Swift]]
*Swift/プロトコル [#d3274344]
オブジェクト指向言語の継承の概念は、クラス継承とインター...
インターフェイス継承をSwiftはプロトコルと呼ぶ。
プロトコル (protocol) は実装を伴わない宣言の集合である。
クラス、構造体、列挙型などを定義するときにプロトコルを指...
そのプロトコルが宣言しているメソッドを実装する。
これにより継承関係のない型でも、プロトコルで宣言された同...
public protocol CustomStringConvertible {
public var description: String { get }
}
プロトコルを使ってクラス(や構造体や列挙型など)を定義する...
「プロトコルを採用 (adopt) する」といい、そのクラス(や構...
「プロトコルに適合 (conform) している」という。
Swiftでプロトコルに含めることができるのは、次の宣言である。
-インスタンスメソッド、タイプメソッド
-演算子による関数の宣言
-インスタンスプロパティ、タイププロパティ
-イニシャライザ
-添字付け
-typealias宣言
プロトコル名は大文字開始のキャメルネームにする。
プロトコルは他のプロトコルを継承することができる。
// { }内はいずれもオプションで順番や個数に制限はない
// [ ]の部分はさらに省略可能
protocol プロトコル名 : プロトコル列 {
[static] func メソッド名 ([仮引数]) [-> 型]
[prefix | postfix] func 演算し ([仮引数]) [->型]
[static] var プロパティ名 : 型 { get [set] }
init([仮引数])
subscript(仮引数) -> 型 { get [set] }
typealias 型名 [= 型]
}
プロトコル Person の例
protocol Personal {
var name: String { get }
init(name: String)
func sayHelloTo(p: Personal)
func saySomething() -> String
}
***メソッドの宣言と定義 [#dc6f0da1]
プロトコルでのメソッドの宣言は、コードブロックは記述しな...
(プロトコルの拡張定義ではコードを記述して、プロトコルのデ...
タイプメソッドを定義するときは static 修飾子を記述する。
***プロパティの宣言と定義 [#p5b24355]
プロパティが読み書き可能の場合はsetとgetを、読み出し専用...
読み出し専用プロパティでも、プロトコルでは var と宣言する...
プロトコルで 読み出し専用として宣言したプロパティを、実装...
実装が格納型か計算型かはプロトコル側では記述しない。
***イニシャライザの宣言と定義 [#lab8ea0c]
イニシャライザを指定することもできる。クラスの必須イニシ...
クラスの実装では required キーワードをつける必要があり、
そのクラスを継承したサブクラスでも同じイニシャライザを定...
(ただし、クラス定義でfinalを指定している場合は、もうサブ...
required を記述する必要はない。)
designated initializer か convenience initalizer の区別は...
class Citizen : Personal {
let name: String // プロトコルを定数で実装する
required init(name: String) { // required が必要
self.name = name
}
func sayHelloTo(p: Personal) {
print("\(p.name)さん、こんにちは")
}
func saySomething() -> String { return "なるほど" }
}
***クラス定義のためのプロトコル [#eaa58848]
クラス(参照型)での実装だけを想定してプロトコルを定義する...
そのような場合は、クラスだけが対象であることを明示するた...
class キーワードを置く。
protocol TripleTappable : class { // 以下、略
protocol Nerberality : class, 別のプロトコル { // 以下、略
クラス限定のプロトコルの場合、メソッドに mutating という...
**プロトコルと型 [#he33aac4]
プロトコルは型として使うことができる。
func printNames(list: [Personal]) {
for p in list {
print(p.name + ": " + p.saySomething())
}
}
typealias による付属型の指定や Self を使って宣言されたプ...
***プロトコルの継承 [#e01f5a1a]
enum Sex { cse Male, Female } // 性別を表す列挙型
protocol HealthInfo : Personal { // プロトコルを継承する
var weight: Double { get set } // 読み書き可能なプロ...
var height: Double { get set }
var sex: Sex? { get } // read onlyなプロパティ
}
***プロトコルの合成 [#bcdaaa51]
複数のプロトコルのUnionのプロトコルを作成できる。
次の例では、NewProtocolという新しいプロトコルを定義し...
一時的に使いたいだけならば protocol<> という記述もできる。
protocol NewProtocol : プロトコル1, プロトコル2 {}
var teller: NewProtocol
または
protocol<プロトコル1, プロトコル2> teller
***プロトコルへの適合を調べる [#c43b7ed4]
Pをプロトコル, 式を exp とする。
- exp is P --- 式 exp がプロトコル P に適合したインスタン...
- exp as P --- 式 exp がプロトコル P にキャストされる。適...
- exp as? P --- 式 exp がプロトコル P のオプショナル型に...
- exp as! P --- 式 exp がプロトコル P のオプショナル型に...
**プロトコルと付属型 [#c9aec7a7]
***ネスト型とプロトコル [#o8cbd247]
次の例では、Elementの定義がなく、プロパティxとyがElement...
protocol VectorType { // 2次元ベクトル型
typealias Element // 付属型の宣言
var x : Element { get set }
var y : Element { get set }
}
プロトコル内で typealias を使って定義される付属型はジェネ...
型の定義にプロトコルが採用されたときその型で実際に使われ...
型パラメータや付属型はコンパイル時に静的に解析される。
struct VectorFloat : VectorType {
var x, y: Float // 付属型に具体的な型を指定した
func onvToDouble() -> VectorDouble {
return VectorDouble(
x: VectorDouble.Element(x), // 型として利用
y: VectorDouble.Element(y)
)
}
}
struct VectorDouble : VectorType, CustomStringConvertibl...
var x, y: Double // 付属型に具体的な型を指定した
var description: String { return "[\(x), \(y)]" }
}
struct VectorGrade : VectorType {
enum Element { case A, B, C, D, X } // ネスト型を定...
var x, y: Element
}
var a = VectorFloat(x: 10.0, y: 12.0)
let b = a.convToDouble()
print(b) // [10.0, 12.0] と表示される
***付属型が適合するプロトコルを指定する [#y315c4f2]
プロトコルを採用した型で動作する共通のメソッドを宣言しよ...
付属型で表される型にどのような操作や演算が可能かを指定で...
そのためには適合するパラメータを指定すればよい。
protocol VectorIntegerType {
typealias Element: IntegerType // 付属型に適合する...
var x : Element { get set }
var y : Element { get set }
}
struct VectorInt: VectorIntegerType {
var x, y: Int
mutating func add(x:Int, y:Int) {
self.x += x; self.y += y
}
}
struct VectorUInt16: VectorIntegerType {
var x, y: UInt16
}
let mx: VectorInt.Element = 10 // VectorInt.ElementはI...
var a = VectorInt(x:mx, y:-7)
a.add(x:10, y:9) // (x: 20, y: 2) になる。
*プロトコルに適合する型の定義方法 [#i4af640c]
プロトコル Equatable と Comparable
ページ名: