読み進めていく本↓
前回⇒「【Swift奮闘記ep9】オプショナル(強制的・暗黙的なアンラップ、オプショナルバインディング)」
やっとの事で「第3章Swiftの基本的な文法」が終わり、「第4章Swiftとオブジェクト指向プログラミング」に入る。
オブジェクト指向って一気にプログラミングっぽくなるなと思うが、それが何かはハッキリわからない。
難しくなると思うけど、頑張って進んでみる!
オブジェクト指向プログラミングとは
オブジェクト指向の概念って言葉で説明されても正直全然わからない。
機能・役割をもったオブジェクト同士がやり取りをしてひとつになってアプリケーションとなる。というような説明だ。
さらに、複雑になりがちなプログラムを理解しやすい形にして、プログラムの柔軟性や保守性を向上させる考え方。
・・・さっぱりわからん。
型
プログラムの中で扱うオブジェクトの「設計図」のことを”型”という。
変数・定数のところで出てきた”型”と同じもの。
型は設計図で、それを元にオブジェクトを作ることをインスタンス化といい、その出来たオブジェクトのことをインスタンスと呼ぶ。
また、イニシャライザによってインスタンスを生成することができる。
イニシャライザはインスタント化するためのツールなのである(?)
具体的に見てみよう。
let fruits = String( )
String型のイニシャライザを使ってインスタンス化して、生成したインスタンスを定数fruitsに代入している。
文字列は与えられていないので、中身は空文字となる。
クラス
Swiftには様々な型や関数が用意されていて(標準ライブラリという)、ここまで「print( )とかString型とかDictionary型とか」を使ってきたが、今後は自分でクラスやプロパティ、メソッドを定義していく。
クラスとはプロパティやメソッドをプログラマーが定義できる型のこと。
class Car {
}
let car = Car( )
class Car {}でクラスを定義して、let car = Car( )でCarクラスのインスタンスを作成して定数letに代入した。
リザルトバーには Carとクラス名が表示されただけ。
この段階ではCar ( )はインスタンスを生成するしかできないが、後々活用していく。
プロパティ
プロパティは値(データ)のことで、大きく分けて格納型プロパティと計算型プロパティの2つがある。
格納型プロパティ
「var プロパティ名 = 初期値」でプロパティを定義するわけだけど、変数・定数を定義するのと何が違うのだろうか。あまり意味がわからなくなってきたが、普段変数・定数を定義したりすることをクラス内では「プロパティを定義する」というだけなのかな?
クラスという独自で作成した型の機能がプロパティ。
つまりString型にuppercased( )という機能があるようなもんか。
ひとつ面白いな〜と思ったのが以下。
class Fruits {
var type = “りんご“
} // クラスを定義
let fruits = Fruits() // インスタンス化
fruits.type // typeプロパティの中身を表示 ⇒りんご
fruits.type = “みかん“ // typeプロパティの中身を変更 ⇒みかん
fruits.type // typeプロパティの中身を表示 ⇒みかん
let foods = Fruits() // 再度インスタンス化
foods.type // typeプロパティの中身を表示 ⇒りんご
インスタンス化し、typeプロパティの中身をみかんに変えているが、新たにインスタンス化してtypeプロパティの中身を表示させると、元々の初期値のりんご、となる。
型の根本は変更されないのだ。(りんごのまま)
計算型プロパティ
何度読んでも意味がわからないのがこちら。計算型プロパティ。どゆこと。
計算型プロパティは値を格納することができない代わりに、何か計算(処理)をしてくれるプロパティ。
具体的な例を見てみると
class Car1 {
var totalMileage = 0 // トータルの走行距離
var currentMileage = 0 // 現在の走行距離
var mileage: Int {
get {
return currentMileage // 現在の走行距離を返す
}
set {
currentMileage = newValue // 代入された値を現在の走行距離に代入する。
totalMileage += currentMileage // トータルの走行距離に現在の走行距離を足す。
}
}
}
これでCar1という方の定義は完了でこれをインスタンス化すると以下のようになる。
let a = Car1( ) // Car1クラスのインスタンス化
a.mileage = 50 // 走行距離50km追加
a.mileage = 20 // 走行距離20km追加
a.totalMileage // 総走行距離を確認
これで総走行距離は70と表示されるはずだ。
どうだろう、さっぱりわからない。一個一個の仕組みはわかるのだが、全体としてぼんやりしている感じがする。
こういう形だ!と認識して慣れるしかないんだろうな、きっと。
いきなり「(数学の)解の公式を覚えてくださいって言われたような感覚と似ているような気がする。
色々な例を見れば納得するかもしれんが・・・いまのところ、パッとしないな〜。
具体的に疑問な点をいうとするならば、currentMileageをreturnしているところとか、結構謎。
あとnewValueってなんだよって。
値を入力してからの流れって、「まずa.mileageに50を代入します」→「50はnewValueとして処理されて現在の走行距離に代入される」→「総走行距離に足される」って感じかな?newValueって一体なんなんだって話だよね、本の説明を見てみよう。
{}の中では、新しく代入された値をnewValueという特別な名前で扱うことができるので、この値を使って任意の処理が行えます。
ということであるが、あまりここで悩んでいても仕方ないので、次に行くこととする。
※追記
newValueについては、インスタンス化した後にmileageプロパティに代入された値のこと。
newValueに代入された値はどんどんtotalMileageに代入されていって、トータルの距離がわかる仕組み。
ただ、currentMileageをreturnしているところについては未だに謎で、totalMileageをreturnとかだったら納得できるんだけど、なんでcurrentMileageなんだろう・・・。
そもそもget構文の必要性を理解していない。
※さらに追記
get構文について、まだ完全に理解できたわけではないのだけど、キーとなる説明は以下だ。
- getのブロック内に書いたコードは、対象のプロパティの値を取得しようとした時に呼び出される。
- get構文の中では、最後に代入された値を保持しているcurrentMileageをただ返しています。
格納型プロパティとは違って、計算型プロパティは値を保持できないので、set構文、get構文を使ってなんとかしているイメージかな。
取得専用の計算用プロパティ
取得専用の計算用プロパティというのがある。以下の通り。
class Car2 {
let maxFuel = 30
var usedFuel = 0
var remaining: Int {
return maxFuel – usedFuel
}
}
let b = Car2( )
b.remaining
b.usedFuel
b.usedFuel = 10
b.remaining
リザルトバーには上記のように表示される。
Car2
30
0
Car2
20
Car2というクラスを定義した。燃料に関するプロパティということはわかるのだが。
先ほどのCar1と仕組みがどのように違うのかがよくわからないという感じ。
※追記
つまりuseFuelに値を入力しているから、useFuel = newValue としてCar1の形でもいけるんじゃね?という疑問がある。
⇒もちろんCar1でもできるが、もっと簡単に取得専用の計算型プロパティの形でやってみようって話。
ちなみにCar1の形でやると
class Car3{
var maxFuel = 30
var usedFuel = 0
var remaining: Int {
get {
return usedFuel
}
set {
usedFuel = newValue
maxFuel = maxFuel – usedFuel
}
}
}
let car = Car()
car.usedFuel = 10
car.remaining
car.usedFuel = 5
car.remaining
Car1もCar2も状況に合わせてどちらも使えるようになりましょうってことだね。
プロパティの謎は深まるばかりだが、なんとなくの理解のまま続けていけばそのうち全体像が見えてモノにできるのではないだろうか、と信じているので、このまま進めていこうと思う。
今回は長くなってしまったが、それほど手こずって頭を使っているということなので良しとしよう。
次回も引き続きプロパティについて説明していく。
コメント