はじめに
私は、現在大学生なのですが、同じ学部の大学生からソフトウェアエンジニアのバイトをできる人が集まりませんでした。そこで今回は使用しているinterfaceをわかりやすく解説していこうと思います。
Goにおけるinterfaceは他言語にも実装されており、JavaやObjective-Cも同様の語句で使用・実装できます。ただ、私の専門がswiftなのでinterfaceと同じ役割のprotocolを使います。 ![]()
説明上はinterfaceを使いますが、コード上ではprotocolと書きます。
そもそもinterfaceとは?
interfaceの説明の前に、、、オブジェクト指向って知ってる?![]()
オブジェクト指向(言語)をざっくり解説
「この世の全てのものはobject(モノ)であり、モノはそれ固有の処理を有する。そのモノが集まってこの世のモノはできている。」みたいな考え方。モノを表現する方法でclassやstructを使用します。
例)荷車:タイヤ(回転して移動する)、荷台(積載物を乗せる)
基本の構成要素は
-
classやstructの持つモノをproperty -
classやstructの持つ処理method
です。
仮に人(Human)クラスを作ると下記のようになる。
↓ swiftだとこんな感じ
class Human {
// これがproperty
var arm: Arm
// 今回の話に関係ないので無視(イニシャライザって言います)
init(arm: Arm) {
self.arm = arm
}
// これがmethod
func bend(angle: Float) {
// ここに何をするか記載
}
}
class Arm {
// これもmethod
func bend(angle: Float) {
// ここに何をするか
}
}
例えば、上のクラスHumanは腕(arm)を持っていることがわかる。腕を持っているので曲げる処理bend(angle: Float)といったmethodがある。
<「あれ、、、Humanだから「腕がある」、「腕が曲げられる」って本当?腕がない人も骨折して曲げられない人もいるよね?」
というわけで、そんな例外を減らそう!!
設計方針
今回の条件は
-
Humanは腕armというpropertyを保有します。四肢が見た目上、揃っていると思ってください。腕がない人は存在しません。 -
Humanは腕を曲げるmethodを保有します。 - 腕を曲げる
methodはarmの曲げるmethodを呼び出します。
これをコードにすると
class Human {
var arm: Arm
init(arm: Arm) {
self.arm = arm
}
func bend(angle: Float) {
self.arm.bend(angle: angle)
}
}
class Arm {
init() {}
func bend(angle: Float) {
print("腕を\(angle)度、曲げます。")
}
}
Human、Armクラスともに内容を見ての通り健常者の腕を想定して作りました。つまり、義手の人や骨折した人は想定できていませんね。そこで、interfaceの出番です。
interfaceとは、、、
interfaceとは、methodやpropertyを保有していることを宣言する道具です。つまり、処理の中身が伴わなくても問題ないということです。
具体的にいうと、、、
「腕のように見えるモノは腕として見做す。」ということです。この「腕のように見えるモノ」をinterfaceといいます。
これをswiftで書き表すと、、、
class Human {
var arm: ArmInterface
init(arm: ArmInterface) {
self.arm = arm
}
func bend(angle: Float) {
self.arm.bend(angle: angle)
}
}
protocol ArmInterface {
func bend(angle: Float)
}
となります。ちゃんと腕のように見えるモノを人は保有していますし腕としての動作を保証しているので問題ありません。ここで、それぞれの腕クラスを作りましょう。それぞれ、class名の後に: ArmInterfaceを書いてArmInterfaceであることを示しています。
腕
class Arm: ArmInterface {
init(){}
func bend(angle: Float) {
print("腕を\(angle)度、曲げます。")
}
}
骨折した腕
class BrokenArm: ArmInterface {
init() {}
func bend(angle: Float) {
print("骨折しているので動かないです")
}
}
義手
class ProstheticArm: ArmInterface {
init() {}
func bend(angle: Float) {
print("ウィ〜んと音が鳴りながら、腕を\(angle)度、曲げます。")
}
}
これで、Humanクラスは腕、骨折した腕、義手を使用できるようになりました。
本当に動くのか確認してみましょう。
let a = Human(arm: Arm())
let b = Human(arm: BrokenArm())
let c = Human(arm: ProstheticArm())
a.bend(angle: 20)
b.bend(angle: 20)
c.bend(angle: 20)
実行結果です。
腕を20.0度、曲げます。
骨折しているので動かないです
ウィ〜んと音が鳴りながら、腕を20.0度、曲げます。
まとめ
interfaceとは「classやstructが〜に見える」と宣言する道具です。
最後に謝罪
この記事において人が腕を持つといった話を出したのはあくまで概念を具体化し説明しやすくするためです。差別的な意図はないですが、ご気分を悪くされましたら申し訳ありません。