第8回 メソッドの挙動を変えるオーバーライド
平井玄
2003/8/16
|
今回の内容
|
第5回「メソッドとコンストラクタはなぜ必要?」では、プログラムの中の同じ処理をメソッドとして独立させることで、プログラムを書く手間を省略できることを説明しました。しかし、メソッドの効用は「手間の省略」だけではありません。Javaではあらゆる処理がクラスのメンバ変数やメソッドを使って記述されますから、メソッドは単なる処理の単位ではなく、「あるクラスに所属するメソッド」という関係の中で理解されるべきです。
| メソッドの役割 |
このことを、前回紹介したHTML文書からプレーンテキスト部分を取り出すプログラムで使ったString型のメソッドで説明しましょう。
if ( source.charAt(pos) != '<' ) { |
HTML文書のソースを格納するために使われたString型のメソッドは以下の3つです。
| source.length() | 変数sourceの長さを取得 |
| source.charAt(<位置>) | 変数sourceの指定した位置の文字を取得 |
| source.substring(<開始位置>,<終了位置>) | 変数sourceの指定した範囲の文字列を取得 |
どのメソッドも、sourceというString型のインスタンスが保持する文字列について、長さを調べたり、文字や文字列を取り出したりするのに使っています。クラスのメソッドは、単に手間を省くのではなく、あるクラスの特定の機能を実現するために使われるのです。length()やcharAt()というメソッドがあることによって、String型の変数sourceは単に文字列を格納する「入れ物」としての役割だけでなく、文字列について調べたり、操作したりするための「道具」として利用できるわけです。このことは、Javaでプログラムを作るときにとても重要です。Javaではあらゆる処理をクラスとして記述していくことになりますので、どのようなクラスを定義し、そのクラスにどのようなメソッドを具体的に用意するかを考えるのがプログラマの仕事になるからです。
このような意味で、前回紹介したHTMLパーサは、実は全然Java的ではありません。元になるHTML文書が固定されているのは説明の都合ですが、プログラムを見ても、扱うデータがHTML文書であり、HTML文書からプレーンテキストを取り出す処理を実現しているのだ、ということが簡単には読み取れないからです。前回のプログラムはString型の変数に格納された文字列の一部を一定のルールに従って取り出しているにすぎません。Java的なプログラムにするには、HTML文書からプレーンテキストを取り出すということを、クラスを使って記述するべきなのです。
いったいどうしてわざわざクラスを使わなければならないのでしょうか? 何かの処理を実現するには、制御文を組み合わせて、つまりプログラムを「順番に実行する」「条件が合致すれば実行する」「繰り返して実行する」という制御構造の3つのパターンとして記述すれば十分のはずです。
ところが、Javaをはじめとするオブジェクト指向のプログラム言語は、これでは不十分と考えます。HTML文書を扱うのであれば、文字列を扱うクラスとしてString型があるように、HTML文書を扱う「HTMLDocument型」のようなクラスを用意するべきだ、と考えるのです。クラスを用いることで、処理の対象となるデータと、そのデータに関する処理をひとそろいの道具として用意しよう、というのがオブジェクト指向的なプログラムの作り方です。
そこで、前回紹介したHTMLパーサを、クラスを使って次のように書き換えてみました。
HTML文書を扱うクラスを使ったプログラム class HTMLDocument { |
前回紹介したプログラムに比べると、プログラムの本体部分が驚くほどすっきりしました。プログラマはもはやプレーンテキストをどのように取り出すのか、知っている必要はありません。HTML文書を扱いたくなったプログラマは、HTMLDocument型の変数を用意するだけで、HTML文書からプレーンテキストを取り出せます。ちょうど文字列を扱うときにString型のメソッドであるlength()がどのように文字数を数えているか知らなくてよいのと同じです。
| HTMLのバージョンアップに対応する |
HTMLにはバージョンがあります。仮にHTMLDocument型がHTML 2.0に準拠したクラスだったとします。ところがクラスを使ってHTML文書を扱えるようになって喜んでいたのもつかの間、HTMLのバージョンが3.2に上がってしまったとしましょう。HTML 3.2には、HTML 2.0では定義されていなかった「<script>」というタグがあり、<script>〜</script>の間には「<」や「>」が「<」「>」にエンコードされずに現れることがあります。これでは、テキスト読み込み中に「<」を読み込んだらタグの始まり、という仕組みが破たんしてしまいます。試しに以下のプログラムを実行してみましょう。
HTML文書を扱うクラスを使ったプログラム class HTMLDocument { |
実行結果
C:\DOCUME~1 \MYDOCU~1\MYJAVA~1>java
ExtractPlainTextWithClass2 |
<script>〜</script>に現れる「>」をHTMLパーサが誤認識してしまい、スクリプト部分を途中までしか読み取れませんでした。これでは困るので、パーサの仕組みを修正することにしましょう。ただし、現在のパーサはHTMLDocumentクラスのメソッドの一部として存在するので、メソッドを書き換えるとHTMLDocumentクラスの動作が変わってしまいます。このように処理が不適切になる場合は元のメソッドそのものを書き換えてしまっても構わないのですが、現在の処理内容を保ちつつ、新たな処理もできるようにしたい場合があります。HTML文書でいえば、HTML 2.0準拠の文書として扱う方法も残したいが、HTML 3.2準拠の文書も扱いたい、というような場合です。
こんなとき、Javaではクラスの継承によってクラス間の関係を記述できるのでした。第4回「クラスの継承の本質を知る」では、平面上の場所を表すクラスを継承し、高さを格納するメンバ変数を導入することで、3次元座標を表すクラスを作りました。
今回も同じように考えればよいのです。HTMLDocumentをスーパークラスとし、HTML 3.2に準拠する方法でプレーンテキストを取り出すサブクラスを作ればよいわけです。しかし、今回はメソッドの機能を変更することになります。座標を表すクラスの継承ではメンバ変数を追加するだけでしたが、メソッドの挙動を変えるにはどうしたらよいのでしょうか?
| メソッドのオーバーライド |
Javaでは、スーパークラスとサブクラスで、概念としては同じことをするのだけれども処理する内容は異なる、という場合に「メソッドのオーバーライド」という方法を使います。HTML 3.2には、「<」の後に空白が続かないのがタグの始まり、というようにタグの始まりに関する定義を変更することで対応しました。HTMLを解釈する方法を切り替えて、メソッドの動作を変更したのが以下のプログラムです。
HTMLDocument型のメソッドをオーバーライドするプログラム class HTMLDocument { |
実行結果
C:\DOCUME~1\MYDOCU~1\MYJAVA~1>java
ExtractPlainTextWithClass3 |
ここでは、HTML 3.2に対応したクラスとしてHTMLDocumentを継承するHTML32Documentというクラスを定義しました。変数docはHTML32Document型として宣言されているため、HTML文書はHTML 3.2対応のパーサで解析されて、適切にプレーンテキスト部分を取り出せました。HTML32Documentでは、スーパークラスであるHTMLDocumentのメソッドshowPlainText()と同名で引数の数も変わらないメソッドを再定義しています。
| 何がオーバーライドされるのか? |
「オーバーライド」とは英語で「決定されたことを覆す」という意味です。以下のプログラムを実行するとどのように表示されるか、考えてみてください。
オーバーライドの意味を考えるプログラム class HTMLDocument { |
上記のプログラムでは、HTML32Document型のインスタンスを、HTML32Document型の変数doc32と、HTMLDocument型の変数doc20に代入しています。「doc32.showPlainText();」という文はスクリプト部分を適切に解釈して表示できると予想できますが、「doc20.showPlainText();」という文はどうなるでしょうか? doc20に代入されているインスタンスはHTML32Document型ですが、変数doc20の型はHTMLDocumentです。
このプログラムを実行すると、次のようになります。
C:\DOCUME~1\MYDOCU~1\MYJAVA~1>java
ExtractPlainTextWithClass4 |
実はメソッドをオーバーライドすると、オーバーライドされたスーパークラスのメソッドは隠されてしまいます。この例のようにスーパークラスの参照型を使っても、実行されるのはサブクラスのメソッドになります。元のメソッドの動作を上書きしてしまうことから、「オーバーライド」と呼ぶわけです。
今回はクラスがデータを格納する単なる入れ物ではなく、「道具」であることを学びました。また、クラスのメソッドをオーバーライドすることで、スーパークラスとサブクラスで概念としては同じだが実際の処理内容が異なるメソッドに同じ名前を付けられることも学びました。次回はHTML文書を操作するクラスを通じて、クラスのメソッドを公開用と内部の作業用に分ける方法を説明します。
いまから始めるJava バックナンバー
- 第1回 Java2 SDKで学習の準備
- 第2回 Javaの変数の本質を知る
- 第3回 クラスを簡単に理解しよう
- 第4回 クラスの継承の本質を知る
- 第5回 メソッドとコンストラクタはなぜ必要?
- 第6回 Javaプログラムの制御構造を理解する
- 第7回 Javaの制御文を使いこなそう
- 第8回 メソッドの挙動を変えるオーバーライド
- 第9回 クラスのメンバに利用制限を付与するアクセス制御
- 第10回 Javaのクラスをグループ化するパッケージ
- 第11回 Javaのクラスの理解を深める
- 第12回 Javaプログラミングにおけるエラー対処
- 第13回 Javaの例外をスマートに記述する
- 最終回 Javaの抽象クラスとインターフェイス
| 「いまから始めるJava」記事一覧 |
ホワイトペーパー(TechTargetジャパン)
- Android NDKでJNIを使用してアプリを高速化するには (2010/3/17)
C/C++やOpenGL ESといったネイティブコードを使うためのNDKとJNIを紹介し、その使い方や注意点を徹底解説します - 調査の難しい「OutOfMemoryError」事例、5選 (2010/3/11)
Java開発者が避けて通れないメモリ不足エラーの基本的な問題切り分け方法と発生につながる事例、対処法を解説 - 究極の問題解析ツール、逆コンパイラJD-Eclipseとは (2010/3/8)
ライブラリ内で例外が発生! そのクラスのソースコードを調べたい!! 自動で逆コンパイルしてくれる無料Eclipseプラグインがあります - いまさら聞けない「Webサービス」の常識 (2010/2/26)
昨今では企業システムでも使われる「Webサービス」の概念やJava標準のJAX-WSを紹介しJBoss WSでサンプルを作成
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
| 「いつかは壊れるサーバ」そんな故障に 迅速で安価に手軽に対応する方法とは? New! |
| 「特権ユーザー」の事件を防げ! 万能権限を持つユーザーの管理方法とは? New! |
| 仮想環境の構築とデータ保護の特効薬?! 実績と信頼性の高いパッケージで安心運用 |
| 仮想環境のバックアップもこれまでどおり 「まるごと取ってまるごと戻す」簡単運用 |
| おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |
| その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |
| 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |
| 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |
- - PR -
お勧め求人情報

**先週の人気講座ランキング**
〜CCNA編〜
| ◆ | TomcatやJBossなどAPサーバ環境に関する 情報を集約! “業務”用APサーバ大百科 New! |
| ◆ | 一気に解説! 最新のクラスタストレージ 「RAIDを超えたストレージ基準」……など New! |
| ◆ | クラウド的ユーザー体験の変化は脅威か? 仮想化技術を使いこなす運用管理術を紹介 New! |

| ◆ | 上司や部下、部署内メンバーとの情報共有 を“ガラッ”と変えるコラボツールとは? New! |
| ◆ | おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| ◆ | 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |

| ◆ | Twitterのアカウントはなぜ突破された? メールによる新手の攻撃手法とその対策 |
| ◆ | もう仮想化のお試しフェイズは終わりだ! Hyper-V 2.0が基幹システムも仮想化 |
| ◆ | 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |

| ◆ | クライアント企業から求められる人材 ⇒IT技術と経営戦略を併せ持つ「戦略家」 |
| ◆ | .NET編集長が実践する「技術情報検索術」 サンプル・コードを簡単に探す“技”は? |
| ◆ | 業務効率と情報セキュリティ対策を両立! 手間なく確実に機密情報を守る方法とは? |

| ◆ | 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| ◆ | 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |

| ◆ | 【CTC事例】約30の基幹システムを統合! 膨大なバッジジョブを制御した方法は? |
| ◆ | 仮想化すればコストは削減できるか? 仮想化に必要な「3つの視点」を解説する |
| ◆ | その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |






