はじめに
私は、現在大学生なのですが、同じ学部の大学生からソフトウェアエンジニアのバイトをできる人が集まりませんでした。そこで今回は使用している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
が〜に見える」と宣言する道具です。
最後に謝罪
この記事において人が腕を持つといった話を出したのはあくまで概念を具体化し説明しやすくするためです。差別的な意図はないですが、ご気分を悪くされましたら申し訳ありません。