【Swift】クラスの使い方まとめ!オブジェクト指向型プログラミングとは?
この記事からわかること
- オブジェクト指向型プログラミングとは?
- Swiftのクラスの使い方とメリット
- ストアドプロパティとコンピューテッドプロパティの違い
- クラスと構造体の違い
- 値渡しと参照渡しとは?
- イニシャライザの使い方
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
オブジェクト指向型のプログラミング言語に欠かせないクラス。Swiftもオブジェクト指向型のプログラミング言語であり、クラスが使用可能です。
今回はSwiftのクラスの使い方と出来ること、メリットなどを自分なりにまとめていきたいと思います。
オブジェクト指向型プログラミングとは?
「オブジェクト指向プログラミング」とはプログラミングの手法(プログラミングパラダイム)の種類の1つです。他にも関数型プログラミングや命令型プログラミング、手続型プログラミングなどがあります。
オブジェクト指向型プログラミングの特徴はオブジェクトと呼ばれるデータ構造を定義してプログラムを記述していくことです。このオブジェクトには固有のデータ(プロパティ)と固有の処理(メソッド)を用意しておき、外部からの呼び出しに応じてデータを操作していきます。
オブジェクトはプロパティやメソッドを持ったデータ構造の雛形や設計図のようなものであり、使用するにはその設計図を元に作成された実体を使用します。これをインスタンスと呼び作成することをインスタンス化と呼びます。
メリット
オブジェクト指向型プログラミングの大きなメリットは扱うデータのスコープ(使用範囲)や使い方を制御しやすいという点です。オブジェクト内でデータとそれを操作するメソッドを完結することで外部からは複雑な操作を意識する必要がなく利用することができます。これをカプセル化と呼びます。
まとめ
- オブジェクト指向型プログラミングはプログラミングパラダイムの1つ
- オブジェクトはデータ構造の設計図
- 使用する際はインスタンス化して使う
- インスタンス化とは設計図を元に実体を作ること
- メリットはデータ情報を隠蔽でき、制御できること
おすすめ記事:Swiftとは?Swift UIとの違いと特徴やメリット
Swiftのクラスとは
Swiftではクラスをclass
を使って宣言します。中には扱うデータであるプロパティ(変数)とメソッド(関数)を定義していきます。記述方法はSwiftの構造体とほぼ同じです。
おすすめ記事:【Swift】プロパティの種類!ストアドプロパティやタイププロパティとは?
class クラス名: プロトコル {
let 変数名
var 変数名
init 関数名 () -> {
return 戻り値
}
func 関数名 () -> {
return 戻り値
}
}
おすすめ記事:【Swift】構造体(struct)とは?クラスとの違いと使い方
クラス名はPascal記法をプロパティとメソッドはCamelCase記法(lower)での命名が推奨されています。
記法 | 説明 | 例 |
---|---|---|
CamelCase記法 | 先頭は小文字で単語ごとに大文字 | $myData |
アンダースコア記法 | 小文字で単語の間をアンダースコア(_)で繋ぐ | $my_data |
Pascal記法 | 先頭と単語の区切りが大文字 | $MyData |
インスタンス化
class
を使って定義したら使用できるようにインスタンス化します。インスタンス化するにはクラス名()
の形式で変数に格納してあげるだけです。これで変数の中にクラスに基づいた実体が生成されます。
class Guitar {
var name:String = ""
}
var g = Guitar() // インスタンス化
g.name = "Gibson" // 値を格納
print(g.name) // Gibson
インスタンス化した変数にはドットシンタックスを使って定義されているプロパティやメソッドにアクセスすることができるようになります。インスタンス化したプロパティに値を格納することも可能です。
プロパティの初期値
クラス内に定義するプロパティには基本的に初期値が必要です。例えば以下のような初期値なしで定義しようとするとエラーになります。
class Guitar {
var name:String
}
エラー
Class 'Guitar' has no initializers
Stored property 'name' without initial value prevents synthesized initializers
プロパティにはストアドプロパティ(stored property)とコンピューテッドプロパティ(computed property)があります。ストアドプロパティは値を保持し、コンピューテッドプロパティは計算式を保持し、結果を返します。
プロパティの種類や宣言方法によって初期化(デフォルト値の明示的な格納)が必要ないプロパティもあります。例えば以下はデフォルト値がなくてもエラーにはなりません。
class Guitar {
var a: Int? // Optional型のストアドプロパティ
var b :Int { return 0 } // コンピューテッドプロパティ(computed property)
var c :Int? { return 0 } // Optional型を許容するコンピューテッドプロパティ(computed property)
}
nil
を許容するOptional型で宣言した変数はデフォルト値がない時自動でnil
が格納されるため「デフォルト値がありません」と言ったエラーが起きなくなります。
プロパティの初期化には後述しているイニシャライザが深く関係してきます。
クラスと構造体の違い
Swiftのクラスと構造体の大きな違いはデータの参照方法です。変数に格納する時が分かりやすく、その際に渡されるのがデータ本体(値)か参照パスかで参照方法が異なります。データ本体の場合は「値型」、参照パスの場合は「参照型」と呼びます。クラスは参照型、構造体は値型になります。これは例を見ると分かりやすいと思います。
struct SName {
var name:String
}
class CName {
var name:String
}
var s = SName() // 構造体のインスタンス化
var c = CName() // クラスのインスタンス化
var sA = s // 変数に格納 値渡し
var cA = c // 変数に格納 参照渡し
s.name = "ame" // 元のインスタンスを変更
c.name = "ame" // 元のインスタンスを変更
print(sA.name) // "" 値型は元が変更されても関係なし
print(cA.name) // "ame" 参照型は元が変更されると更新
sA.name = "foo" // コピーしたインスタンスを変更
cA.name = "foo" // コピーしたインスタンスを変更
print(s.name) // "ame" 値型の元のインスタンスは変更されない
print(c.name) // "foo" 参照型は変更されると更新
値型
その時時点のデータをそのままコピーするだけなので、元のインスタンスとはリンクしていない
参照型
データが格納されているメモリの参照を渡すだけなので、「s」も「sA」も読みにいく場所は同一になるので変更が影響し合う
プロパティをメソッドから変更する
構造体ではメソッドからプロパティを変更するにはmutating
というキーワードを付与しないとエラーになってしまいますが、クラスの場合は何も付与することなく変更が可能です。
class CName {
var name:String = ""
func changeName(){
self.name = "Johnny"
}
}
var c = CName()
c.changeName()
print(c.name) // Johnny
イニシャライザ
イニシャライザとはインスタンス化の際に必ず実行されるメソッドのことです。メソッド名はinit
で固定されており、関数を定義する意味のfunc
は必要ありません。呼び出す時も関数名は省略することができます。
class Guitar {
var name: String
var price: Int
init(name:String,price: Int){
self.name = name
self.price = price
}
}
// インスタンス化時に実行される
// 今回はプロパティへの値の格納
var g = Guitar(name: "Gibson", price: 215000)
イニシャライザは主にクラスを初期化(initialize)するために使用されます。定義しているプロパティに適切な初期値をセットすることで整合性を保つことが目的です。イニシャライザは明示的に指定しない場合、条件によっては暗黙的に生成されます。
例えば宣言しているすべてのプロパティにデフォルト値を渡せば明示的な初期化は不要になります。記述が不要なだけで内部では暗黙的に自動でイニシャライザが実装されます。これを「Default Initializer」と呼びます。
class Guitar {
var name: String = ""
var price: Int = 0
// init()が実装
}
ちなみに構造体の場合はデフォルト値がなくてもエラーになりません。これは「Memberwise Initializer」と呼ばれるイニシャライザが実装されているからのようです。
struct Guitar {
var name: String
var price: Int
}
イニシャライザについてはこちらの記事がとても参考になります。
Qiita記事::Swiftとイニシャライザ
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。