• 検索結果がありません。

CentroidExample.java ( 参照型配列 Point[])

ドキュメント内 i I Java Java Java (ページ 165-168)

第 2 章 Java 言語の基本的な文法 I 5

3.22 CentroidExample.java ( 参照型配列 Point[])

public class Problem0302 { int a;

public static void main(String[] args) { a = 123;

} }

package section0302;

public class Problem0302 { int a;

public static void main(String[] args) { this.a = 123;

} }

では、 mainメソッドの中にどのように書いたら変数aに123 を代入できますか。

逆に、最初のプログラムで mainメソッドの中身a = 123;を変えずにツジツマの合う (?) ようにするには、どうし たら良いでしょう。

new Point( 1.2, 0.9 ), new Point( 1.5, 3.2 ), new Point( 1.7, 2.2 ), new Point( 3.0, 0.7 ), new Point( 3.3, 3.1 ), };

Point.centroid( points ).print();

} }

ソースコード3.23 Point.java (メソッドcentroidの追加) package section0302;

//平面上の点のためのクラス public class Point {

private double x;

private double y;

   :

// 点配列の重心を求めるクラスメソッド

public static Point centroid( Point[] points ) { double xsum = 0.;

double ysum = 0.;

for( Point p : points ) { xsum += p.x;

ysum += p.y;

}

return new Point( xsum/points.length, ysum/points.length );

} }

さて、 mainメソッドの12行目の処理Point.centroid( points ).print();は解読出来ましたか?

左から順に読んでくれればOK なのですが、まずは Point.centroid( points )これは Pointクラスのクラスメ ソッドcentroid() の引数に点の配列pointsを渡していますね。このメソッドは(この後作ってもらうわけですが)

重心をPoint 型インスタンスとして返してくれます。つまり、その重心自体もフィールドやメソッドを持っているの

です。従って、その.print()なわけですから、その重心点の持つインスタンスメソッド print()を動かして(情報 を出力せよ)!という意味です。ドットでつなげることで、2つのメソッドを連続的に使って処理をしているわけです。

もちろん以下のように一旦 Point型インスタンスcentroidを作成してから、print()を動かす!と書いても良い ですよ。

// Point.centroid( points ).print(); の代わりに Point centroid = Point.centroid( points );

centroid.print();

} }

ところで、CentroidExample.javamainの中のエラー(?)に気づいた人いますか?

配列pointsの最後の点 new Point( 3.3, 3.1 ) の後に余分なカンマが!しかし実はこれ、知っていて付けていま す(コンパイラがエラーにしていないでしょ)。これは C言語から受け継いだ隠れた仕様で(C++でもOK)、配列の最 後の要素の後ろに余分なカンマを付けてもエラーとしない!というものです (文法に厳しい Javaもこの仕様は継承し ているのです)。理由は、データのコピペが楽にできる、というのが目的だったようですが、和田はあまり好きな仕様

自動車を運転するドライバーは、各車種ごとにそのアクセルペダルの先にどんな機構が隠されているのか知らなくて もペダルを踏めばエンジン回転数が上がることを知っています。このブラックボックス化のことを「カプセル化」と言 います。カプセル化は、データや処理に対しユーザに必要なものだけ公開し不必要なものはいんぺい蔽する操作を言います。

カプセル化により、

• 限定された操作以外では利用できないようにする

• 不必要なものが見えないようにできる

• 中身を改変されることを防止できる

• オブジェクト間の関連が減ることで制御しやすくなる

• 公開した操作を改変しない限りは、外部に影響を与えない内部のバージョンアップが可能になる

Javaのプログラムにおいては、メンバー(フィールド・コンストラクタ・メソッド)ごとに適切なアクセス制限をか けることで、カプセル化が実現できます。

3.3.1 アクセス制御

カプセル化を実現させるためには、各メンバーごとにどこまで公開(利用・改変)を可能にするか?を設定すること から始めます。ここまでに説明なしにちょくちょく出てきた public やprivate が、そのための「アクセス修飾子

(access modifier)」です。Javaでは、全てのメンバー (クラス・コンストラクタ・フィールド・メソッド)にアクセス

修飾子を付けることができます。まずはそれぞれに付けられるアクセス修飾子を表でまとめましょう。アクセス修飾子 には、修飾子を書かないという選択(package-privateとも呼ばれる)を含めて4種類あります。

図3.3 アクセス修飾子

メンバー

修飾子 private

省略

protected public (package-private)

クラス  × ×

コンストラクタ

フィールド(変数)

メソッド

クラスのアクセス制限に「private」と「protected」が選択できない以外は、いずれのメンバーも全ての修飾子を使 用することができます。ただ、ここでもまたちょっと嘘があって、「内部クラス(inner class)」というクラスでは全て の修飾子が利用できます。「内部クラス」は後で説明しますが、この授業では触れないかな。

メンバーにアクセス修飾子を付けるには、型宣言の際に先頭に書きます。例えば、private int x = 123; や public static double[] x = new double[100];なんて感じですね。以下で1つずつ見ていきましょう。

3.3.2 private

privateは、最も制限の強いアクセス修飾子で、コンストラクタ・フィールド・メソッドに付けることが出来ます。

この修飾子が付いたメンバーは、含まれるクラスの外からは直接アクセスすることができません。アクセスできるの は、そのクラス内部のメンバーからのみです。直接アクセスするとは、次のような処理を言います。

ソースコード3.24 PrivateFieldExample.java (private fieldへ直接アクセス)

ドキュメント内 i I Java Java Java (ページ 165-168)