toString のオーバーライド
println したら、暗号が出てきた
作ったオブジェクトの中身を確かめようとして、そのまま出力してみます。
Java
class Cat {
String name;
int age;
Cat(String name, int age) {
this.name = name;
this.age = age;
}
}
Cat c = new Cat("タマ", 3);
System.out.println(c); // Cat@1b6d3586出てきたのは Cat@1b6d3586 です。クラス名と @ と、意味の分からない英数字。名前も年齢も、どこにもありません。
これは壊れているわけではありません。Java のすべてのクラスは、何も書かなくても toString() というメソッドを最初から持っていて、println は渡されたオブジェクトのそれを呼んで表示します。標準の toString() が返すのが、この「クラス名 + @ + 識別用の数値」という形なのです。人間向けではないだけです。
出し方を自分で決める
自分のクラスで toString() を書き直せば、この表示を好きな形に変えられます。
Java
class Cat {
String name;
int age;
Cat(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "ねこ " + name + " " + age + "歳";
}
}
System.out.println(c); // ねこ タマ 3歳println(c) の行はさっきと 1 文字も変わっていません。呼ばれる toString() の中身が入れ替わっただけです。もともとあるメソッドを自分のクラスで書き直すことを オーバーライド と呼びます。
呼ばれるのは println からだけではありません。+ で文字列につないだときも、同じ toString() の結果が使われます。
Java
System.out.println("いま選んでいるのは " + c);
// いま選んでいるのは ねこ タマ 3歳書き方には決まりがあります。名前は toString、引数はなし、戻り値は String。3 つのうち 1 つでもずれると、それは別のメソッドになり、println は見向きもしません。
上にある
@Overrideは、コンパイラへの「これは書き直しのつもりです」という申告です。付けておくと、tostringと打ち間違えたり引数を足したりしたときに、その場でエラーになります。付けないと何事もなくコンパイルが通り、いつまでもCat@1b6d3586が出続けて「書いたはずなのに反映されない」と悩むことになります。
やってみよう
右のエディタで pointToString(int x, int y) を完成させます。座標を表す Point の toString() が返すはずの文字列を、static メソッドで組み立てる練習です。
書式は課題の要件どおりに、カンマのうしろの半角スペースまで正確に合わせてください。丸カッコを [] や {} にすると落ちます。マイナスの値は + でつなぐだけでそのまま文字列になるので、特別な処理は要りません。
緑になったら、エディタに Point クラスを書き起こして、@Override 付きの toString() を実装し、System.out.println(new Point(3, 4)); を実行してみてください。toString() を書く前と後で同じ 1 行がどう変わるかを見ておくと、なぜ自作クラスには毎回これを書きたくなるのかが分かります。
要件
- クラス名は
Solution、メソッド名はpointToStringにすること - メソッドは
public static String pointToString(int x, int y)のシグネチャで、引数 2 つを受け取る - 戻り値は
"Point(x, y)"形式の文字列 (,の後ろに半角スペース 1 つ、括弧は丸括弧())
入出力例
pointToString(3, 4) → "Point(3, 4)"
pointToString(0, 0) → "Point(0, 0)"
pointToString(-1, -2) → "Point(-1, -2)"