導入
今回のテーマであるAPIはApplication Programming Interfaceの略であり、一般的にイメージするweb APIとは異なる意味で使われているようである。もしかしたら私だけの可能性もあり。 いろいろと勘違いしていたところも多いので、ここで改めて各用語の定義を確認。
公式ドキュメント
まさかのここから笑 私自身最初にこの記事をまとめていた当初はAPIっていわゆる公式ドキュメントでしょと思ってましたが、公式ドキュメントはこのAPIについての解説書であるAPIリファレンスを含んだもっと懐の深い存在でした。
API
ソフトウェアやプログラム同士が機能を共有し、連携するためのインターフェース(仕様・窓口)のこと。今この記事のなかだけで通じる説明で言えば、Java(あらかじめ用意された機能群)と、プログラム(開発者が書くコード)同士が機能を共有し、連携するためのインターフェース、というイメージです。
APIリファレンス
前述の通り公式ドキュメントの一部であり、各APIの取扱説明書のようなものである。
暗黙の継承
このAPIリファレンスを確認することで理解しておきたいことが、Javaの全てのクラスはObjectクラスを継承しているということである。
例として、
public class Empty {}
というクラスを定義したとしても、暗黙的に以下のようなコードと同じになる。
import java.lang.Object
public class Empty extends Object {}
Objectクラスの存在価値
先ほど説明したようにすべてのクラスがObjectをスーパークラスとしていることから、これを以下のように利用できる場面がある。
- 多態性を利用できる
- Objectをデータ型にしてどんなインスタンスでも受け取れる
- 全クラス共通で使用できるメソッドがある
例1:多態性を利用して、以下のコードが成り立つ。
public class Main {
public static void main(String[] args) {
Object o1 = new Empty();
Object o2 = new Hero();
Object o3 = "こんにちは";
}
}
例2:どんなインスタンスでも受け取れる
public class Printer {
public void printAnything(Object o) {
System.out.println(o.toString());
}
}
例2のコードからもわかるようにすべてのインスタンスが共通してtoString()のようなメソッドを使用できる。APIリファレンスから確認できるように、Objectクラスのインスタンスメソッドは11種類あるが、その中で、以下の3つのメソッドは、クラスを作成する際にオーバーライド(再定義)しておくことで、クラスが格段に扱いやすくなり、開発やデバッグの大きな助けとなる。
- toString()
- equals()
- hashCode() ※equals()をオーバーライドする場合は、必ずペアでオーバーライドする必要がある
toStringメソッド
以下のコード例からわかるようにインスタンスを標準出力させるとtoString()で出力させた内容と同じになることがわかる。
public class Main {
public static void main(String[] args) {
Hero h = new Hero();
h.name = "ミナト";
h.hp = 100;
System.out.println(h.toString());
System.out.println(h);
}
}
//出力結果
//Hero@5ca881b5
//Hero@5ca881b5
これからわかるように自身に都合の良い内容が返るようにtoStringメソッドはオーバーライドしておくとわかりやすく利用しやすい。
equalsメソッド
まずは似たような処理の記述方法として==とequalsメソッドの差異を確認
| コード | 処理内容 |
|---|---|
| == | 完全に同一の存在かどうか |
| equals() | 同じ内容であるかどうか、同一でなくても内容が一緒であればよい |
では以下のコードは異なるインスタンスを作成するが、その内容を同じにした場合をequalsで比較した場合である。
public class Main {
public static void main(String[] args) {
Hero h1 = new Hero();
h1.name = "ミナト";
h1.hp = 100;
Hero h2 = new Hero();
h2.name = "ミナト";
h2.hp = 100;
if (h1.equals(h2) == true) {
System.out.println("同じ内容です");
} else {
System.out.println("違う内容です");
}
}
}
これをequalsをオーバーライドせずにいた場合、先ほどの定義でいえば、同じ内容ですと出力されることを期待するが、実際には"違う内容です"と出力される。もしオーバーライドをしていなければスーパークラスであるObjectから継承されるequals()は以下のコードであるためである。
public boolean equals(Object o) {
if (this == o) { return true; }
else { return false; }
}
継承されたメソッドではこのようなコードでの比較になり、結局==での等値比較となってfalseを返してしまう。そのため、クラス作成時にどのような状態であれば等価とみなすかをオーバーライドで示しておくことが望ましい。
hashCodeはコレクションフレームワークを学習していない場合は理解が難しいとのことで、今回は割愛