前回執筆した記事でJavaのチュートリアルがとても分かりやすいことに気づきました。
Javaチュートリアルのオブジェクト指向解説が分かりやす過ぎる
またチュートリアルを参考に、今回はプログラミング言語で混同しやすいインターフェースの実装とクラスの継承に関してアプトプットします。
前回の記事で、「現実世界の物体について考えると分かり易い」と書きましたが、
今回も同様にObjectを物体と考えてClass、Interfaceを解説します。
クラスとは
In the real world, you'll often find many individual objects all of the same kind. There may be thousands of other bicycles in existence, all of the same make and model. Each bicycle was built from the same set of blueprints and therefore contains the same components. In object-oriented terms, we say that your bicycle is an instance of the class of objects known as bicycles. A class is the blueprint from which individual objects are created.
前回の記事より、例えば自転車という物体(Object)は、
現在のギア、現在のペダルのリズム、現在の速度といった状態(Field)を持っています。
また、ギアの変更、ペダルのリズムの変更、ブレーキの適用という動作(Method)も持っています。
そしてその自転車を作る為には、設計図が必要なことは想像がつきます。
この設計図が 「Class」 になります。
class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
void printStates() {
System.out.println("cadence:" +
cadence + " speed:" +
speed + " gear:" + gear);
}
}
現実の世界では、同じメーカーあるいは同じモデルなど、同じ種類の自転車が数多く存在します。
それらの自転車は同じ設計図から作られ、同じ部品を含んでいます。
※コードの再利用性
インスタンスというオブジェクト指向の用語がありますが、Instanceは日本語で「実例」です。
設計図(Class)を使用して、実際に作ってみた自転車(Object)をInstanceと呼ぶ、といった感じでしょうか。
インターフェースとは
An interface is a contract between a class and the outside world. When a class implements an interface, it promises to provide the behavior published by that interface. This section defines a simple interface and explains the necessary changes for any class that implements it.
Interfaceとは「契約・約束」であると言っています。
またそれはClassそのものの約束ではなく、「Classと外界との間」「Interfaceのふるまい」の約束を指します。
どうやらInterfaceとは、 「Classと外界の間にある、抽象的な何か」 のようです。
もう少し深ぼってみましょう。
As you've already learned, objects define their interaction with the outside world through the methods that they expose. Methods form the object's interface with the outside world; the buttons on the front of your television set, for example, are the interface between you and the electrical wiring on the other side of its plastic casing. You press the "power" button to turn the television on and off.
急に自転車からテレビの具体例になりましたね…
私なりに自転車で解釈してみます。
Methodは、外界とObjectのInterfaceを形成するとあります。
Interfaceとは日本語で「境界・接点」です。
自転車にはブレーキの適用という「動作」があると書きました。
ではもし「接点」が決まっていないと、この動作はどうなるでしょうか?
直接タイヤに木の棒を噛ませたり、直接両足でタイヤを挟んでブレーキをかける使用者が現れるかもしれません。
そして「僕は普通に自転車に乗っていたのに自転車が壊れた!」とクレームを言って来るかもしれません。
しかし「接点→約束」が決まっていないので、自転車メーカーは「故障の原因は使用者にあります!」と、言うことができませんし、その原因に気づけません。
逆を言えば、
Interface(約束)を決めておくことで、Error(故障)の原因に気づきやすいObject(自転車)を実装することができます。
インターフェースと継承
ここでは物体の話から離れて、プログラミングの話になっていきます。
ClassとInterfaceの違いに着目していきます。
One significant difference between classes and interfaces is that classes can have fields whereas interfaces cannot. In addition, you can instantiate a class to create an object, which you cannot do with interfaces. As explained in the section What Is an Object?, an object stores its state in fields, which are defined in classes.
ClassとInterfaceの違いについてずばり説明してくれています。
その一つは、ClassはFieldを持つことができるのに対し、InterfaceはFieldを持つことができないということです。
また、Classをインスタンス化してObjectを作成できますが、Interfaceではこれを行うことはできないとも言っています。
ClassはObjectの設計図です。
Objectは物体なので状態を持ちますが、Interfaceは約束なので状態を持たず、約束からは物体を作れません。
One reason why the Java programming language does not permit you to extend more than one class is to avoid the issues of multiple inheritance of state, which is the ability to inherit fields from multiple classes.
The Java programming language supports multiple inheritance of type, which is the ability of a class to implement more than one interface. An object can have multiple types: the type of its own class and the types of all the interfaces that the class implements. This means that if a variable is declared to be the type of an interface, then its value can reference any object that is instantiated from any class that implements the interface. This is discussed in the section Using an Interface as a Type.
もう一つの違いは、Classは複数のClassを継承することができないが、複数のInterfaceを実装することはできることです。
これはFieldの多重継承を回避する為です。
Fieldを複数の親クラスから多重継承できてしまうと、もしそれぞれの親クラスが同名のFieldを持っていた場合、子クラスはどのField優先すれば良いか分からなくなってしまいます。
Methodにおいても同じで、同名のMethodが存在していると、どのMethodを使用すれば良いか分からなくなってしまいます。
ただInterfaceは、複数実装することか許されています。
その理由は、Interfaceが状態を持たないことと、「⚪︎⚪︎という名前のMethodを実装してね」という約束だけで、Methodの中身が無いからです。