オーバーライド
今回紹介した本の中で『わかりやすいJava オブジェクト指向編』がオブジェクト指向に関して、細かな所まで説明が行き届き一歩抜きんでている感があります。600ページを超える長さを敬遠する人もいるかもしれませんが、長くて冗長な説明に陥ることなく、長さに応じた充実感があります。オーバーライドの細かい規則も『わかりやすいJava オブジェクト指向編』にはあります。
オーバーロードではアクセス修飾子に制限はありませんが、オーバーライドではよりアクセス範囲の広いものみ指定可能です(例えばprotectedからpublicなど)。また、オーバーロードではthrowsする例外も制限はありませんが、オーバーライドでは細かい規則があります。『わかりやすいJava オブジェクト指向編』p310を参照ください。金銭的に余裕があれば、『わかりやすいJava オブジェクト指向編』はオブジェクト指向を学ぶ上でぜひ用意しておきたい本です。長文が苦手でも、他の本を読んでよく理解できなかったものなどを拾い読みするだけでも助かるいい本です。
ポリモルフィズム
多相性、多態性とも呼ばれます。ポリモルフィズムはオーバーライドメソッドが子クラスと親クラスで異なる働きをすることを指します。教科書ではそこまでしか説明されませんが、実務では親クラスと子クラスという異なる階層で同じ名前のメソッドを呼び出すことはあまりありません。ポリモルフィズムが役に立つのは1つの親クラスのメソッドを複数の子クラスがオーバーライドする場合です。言葉では分かりづらいためコードで説明します。リスト1が親となるShapeクラスです。getArea()というメソッドを持っています。それを継承する子クラスとして、リスト2のSquareクラス、リスト3のCircleクラス、リスト4のEquilateralTriangle(正三角形)クラスがあり、それぞれgetAreaメソッドをオーバーライドしています。リスト5のPolymorphismExecクラスがポリモルフィズムを確認するためのクラスです。
001:package jp.kawakubo.codezine.polymorphism.sample;
002:
003:public class Shape {
004:
005: public double getArea() {
006: return 0.0;
007: }
008:
009:}
001:package jp.kawakubo.codezine.polymorphism.sample;
002:
003:public class Square extends Shape{
004:
005: public double lengthOfSide = 0.0;
006:
007: public Square(double lengthOfSide) {
008: this.lengthOfSide = lengthOfSide;
009: }
010:
011: @Override
012: public double getArea() {
013: return this.lengthOfSide * this.lengthOfSide;
014: }
015:
016: public String toString() {
017: return "1辺が" + this.lengthOfSide + "の正方形(Square)";
018: }
019:}
001:package jp.kawakubo.codezine.polymorphism.sample;
002:
003:import static java.lang.Math.*;
004:
005:public class Circle extends Shape{
006:
007: public double radius = 0.0;
008:
009: public Circle(double radius) {
010: this.radius = radius;
011: }
012: @Override
013: public double getArea() {
014: return PI * this.radius * this.radius;
015: }
016:
017: public String toString() {
018: return "半径が" + this.radius + "の円(Circle)";
019: }
020:}
001:package jp.kawakubo.codezine.polymorphism.sample;
002:
003:import static java.lang.Math.*;
004:
005:public class EquilateralTriangle extends Shape {
006:
007: public double lengthOfSide = 0.0;
008:
009: private static final int FOMULA_NUMBER_3 = 3;
010: private static final int FOMULA_NUMBER_4 = 4;
011:
012: public EquilateralTriangle(double lengthOfSide) {
013: this.lengthOfSide = lengthOfSide;
014: }
015: @Override
016: public double getArea() {
017: //正三角形の面積を求める公式を使用
018: return sqrt(FOMULA_NUMBER_3) * this.lengthOfSide * this.lengthOfSide / FOMULA_NUMBER_4;
019: }
020:
021: public String toString() {
022: return "1辺が" + this.lengthOfSide + "の正三角形(EquilateralTriangle)";
023: }
024:}
001:package jp.kawakubo.codezine.polymorphism.sample;
002:
003:public class PolymorphismExec {
004:
005: public static void main(String[] args) {
006:
007: Shape[] shapes = new Shape[3];
008: shapes[0] = new Square(10.0);
009: shapes[1] = new Circle(5.6418958354775630148481013748);
010: shapes[2] = new EquilateralTriangle(15.196713713031851);
011:
012: for (int i = 0; i < shapes.length; i++) {
013: System.out.println(shapes[i].toString()
014: + "の面積は" + shapes[i].getArea() + "です。");
015: }
016:
017: }
018:
019:}
PolymorphismExecクラスの8行目から10行目でSquare、Circle、EquilateralTriangleのインスタンスをshapesという配列要素に代入しています。ポリモルフィズムは14行目で使用しています。shapesの配列要素はShape型ですが、実際に実行されているのは子クラスのメソッドの内容です。図1が実行結果です。それぞれのメソッドが実行されていることが確認できます。ポリモルフィズムの実際の活用例です。
なお、CircleクラスとEquilateralTriangleの3行目で静的インポート宣言を行っています。

