今回の記事ではオブジェクト指向の重要な機能であるインターフェースとポリモーフィズムについて解説していきます。
インターフェイスを使いこなせるようになるとプログラム全体の管理がしやすくなります。また、Unityなどフレームワークやライブラリはインターフェイスを使ってその機能を拡張できるようになっています。
前回の記事:
インターフェース(interface)とは
インターフェース(interface)とは派生先で必要になるメンバのみを宣言でき、継承することを前提とした型になります。
インターフェースは継承を前提としているため、メソッドは全て抽象メソッドになります。
派生先のクラスではインターフェースで宣言されたメンバを必ず定義する必要があり、またそれらにはpublicアクセス修飾子をつけないといけません。
インターフェースは基底クラスとは異なり一つのクラスに複数個継承できます。
また、インターフェースを継承したインターフェースも定義することができます。その時は継承元のメンバと被らない様にインターフェースのメンバを宣言する必要があります。
同様に抽象クラスにもインターフェースを継承することができます。
書き方は以下の様にクラスと似たものになります。
interface <名前> { ... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//IGameObjectMoveというインターフェースを定義する。 interface IGameObjectMover { Vector3 GetMove(); } //IGameObjectMoverを継承したクラス。 // インターフェースの定義は継承先に依存している。 class Move1 : IGameObjectMover { public float Speed = 0f; public Vector3 GetMove() { return new Vector3(Speed, 0, 0); } } class Move2 : IGameObjectMover { public float Speed = 0f; public Vector3 GetMove() { return new Vector3(0, Speed, 0); } } |
【実践】Unityでインターフェースを使ってみよう!
それでは実際にUnityでインターフェースを使用してみましょう!
今回のサンプルではIChangeMeshColor
というインターフェースを定義し、それをSampleコンポーネントに継承させています。
IChangeMeshColor
インターフェースはUnityEngine.MeshRenderer
の色を変えるためのメンバを宣言したものになります。(サンプルのものは色を変える一例なので、これと同じことを実現するインターフェースは色々あります。)
IChangeMeshColor
インターフェースには3つのメンバがあり、Sampleコンポーネントではそれらを定義しないといけません。定義内容に関しては特に制約はないので継承先のクラス側で自由に定義することができます。
インターフェースはそれを使用する際に必要となるメンバがあることを保証しますが、実際にどう動作するのかは継承先のクラスの実装に依存しています。
インターフェースはあくまで宣言したメンバがあることを教えてくれるだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using UnityEngine; public interface IChangeMeshColor { MeshRenderer Mesh { get; } Color MeshColor { get; } void ChangeMeshColor(); } public class Sample : MonoBehaviour, IChangeMeshColor { [SerializeField] MeshRenderer _mesh; [SerializeField] Color _color; void Update() { ChangeMeshColor(); } //インターフェースのメンバを定義している。 public MeshRenderer Mesh { get => _mesh; } public Color MeshColor { get => _color; } public void ChangeMeshColor() { if(Mesh != null) Mesh.material.color = MeshColor; } } |
ポリモーフィズムという考え方
インターフェースおよびクラスの継承に関係するプログラミングにおける考え方にポリモーフィズムというものがあります。
ポリモーフィズム(Polymorphism)は直訳すると多態性、多様性などという意味になります。
ちょっと抽象的な単語なため想像しづらいですが、似たようなものを同じ形式で扱うようにする的な意味合いでいいと思います(※)。
(※かなり個人的な解釈が含まれています。)
ポリモーフィズムはプログラマーが持つプログラミングの考え方、哲学が反映されやすいので、どうしても抽象的で小難しい説明になるのですが、ここでの説明は一つの解釈と捉えていただけると幸いです。
似た機能を一つの型にまとめて、違う部分は継承した型で実装する考え方
基本的にポリモーフィズムに従った作りのオブジェクト指向プログラミング言語は、アプリの機能を大雑把にまとめた型を複数個定義して、詳細な処理はその型を継承した型で実装していくことを想定した設計になっています。
アプリを作っていくと似たような処理やデータが出てくるものなのですが、それらを毎回異なる書き方で実装していくと処理の使い回しができなくなります。それに合わせてアプリの実装状況が把握しづらくなり、どんどんと人が管理できないものへと成長してしまうのです。
そのようなことを避けるためオブジェクト指向プログラミング言語では似たものはある一つの型にまとめて、ちょっと異なる部分はその型を継承した型で実装することを簡単に書けるようにした言語設計になっています。
基本はこの考えでいいのですが、オブジェクト指向という考え方を考案した方々は実際に作っていくうちに
- インターフェースという型の使い方のみを持つものがあると便利と気付いたり、
- インターフェースに依存するように作ると修正しやすいことにも気がついたり、
- 型でアプリの構成を形作ったりすると全容が把握しやすい
と発見していったのでしょう。(おそらくですが…。実際とても便利なものになっています。)
以上、個人的な見解でした。
まとめ
今回の記事ではインターフェースについて解説してきました。簡単にまとめると次のようになります。
- インターフェースは継承先のクラスで宣言するメンバを定義するもの。
- インターフェースによって型が使える機能とその実装を分離することができる。
- ポリモーフィズムはオブジェクト指向の考え方そのもの。インターフェースや基底クラスなどで型の使い方を記述し、継承先で詳細な処理を定義、実際に使用する時はインターフェースを使う考え方。
- ポリモーフィズムは人々によって色々な解釈があり様々なものに例えられているが、アプリ開発をしやすいように開発方法をまとめた考え方。
- アプリ開発ではインターフェースに依存するように作ると汎用性が高まり修正しやすい。
それでは次の記事に行ってみましょう!
コメント