コンストラクタ(Constructors)
Triangleクラスはassign()メソッドを用いて,そのオブジェクトの初期化を行っています.しかし,オブジェクトが宣言されたときに,初期化するほうがより自然です.そこで,Javaではクラスオブジェクトに対して,初期化が行えるようにコンストラクタメソッドを用意しています.
コンストラクタは特殊なメソッドで,オブジェクトが宣言されると自動的に呼び出されます.つまり,Triangle t = new Triangle()で,Triangleクラスのオブジェクトtが作成されますが,実はコンストラクタが自動的に呼び出されたのです.コンストラクタは,クラスのオブジェクトを作る関数です.そのため,コンストラクタはクラスと同じ名前を取ります.
解答
public コンストラクタ名(型 引数) |
class TriangleConstructor
{ private double base, height; public TriangleConstructor(double b, double h) { base = b; height = h; } public double area() { return base*height/2; } public void display() { System.out.println("底辺" + base + "高さ" + height + "の三角形の面積は" + area()); } public static void main(String[] args) { Triangle t = new Triangle(18,24.5); t.display(); } } |
実行結果
Triangle t = new Triangle(18,24.5)により,baseとheightを持つオブジェクトtが作成され,18と24.5がそれぞれbaseとheightに渡されます.
上の例題で,底辺が10,高さが20の三角形オブジェクトobj2をコンストラクタを用いて作成し,その面積を求めなさい. |
ここで,Triangleクラスとそのインスタンス化されたオブジェクトの関係を図で表すと次のようになります.
クラスは1つ以上のコンストラクタを持つことができます.
メソッドへのオブジェクトの引渡し
メソッドに引数としてデータを渡すのと同じように,オブジェクトを引数として渡すことができます.それには,渡すオブジェクトの型を使用してメソッドの仮引数を宣言します.
解答 面積の2乗を求める関数をdouble sqArea();とします.
class SqAreaOfTriangle
{ private double base, height; public SqAreaOfTriangle(double b, double h) { base = b; height = h; } public double sqArea() { double a = base*height/2; return a*a; } public void display() { System.out.println("底辺" + base + "高さ" + height + "の三角形の面積の2乗は" + sqArea()); } public static void main(String[] args) { SqAreaOfTriangle t = new SqAreaOfTriangle(18,24.5); t.display(); } } |
実行結果
クラス変数とクラスメソッド
すでに述べたように,クラスは「フィールド」と「メソッド」というい2種類のメンバを持っています.このフィールドとメソッドは厳密にはそれぞれ二つの性格のものに分けられ,計4つに分類されます.
ここでは,特殊なフィールド変数について学びます.Triangleクラスのオブジェクトを作成すると,それぞれのオブジェクトのbaseやheightに値を代入したり出力したりすることができます.つまり,各オブジェクトごとにフィールド変数に値を格納することができます.このことを,フィールド変数base, heightはオブジェクトに関連付けられているといい,このフィールド変数をインスタンス変数といいます.また,display()メソッドも,オブジェクトを作成することによって,呼び出すことができます.このメソッドもオブジェクトに関連付けられているといい,このメソッドをインスタンスメソッドといいます.このように通常は,メンバはオブジェクトに関連付けられています.
ところが,クラスはオブジェクトに関連付けられていないメンバを持つことができます.これをクラス全体に関連付けられているといいます.クラスに関連付けられているフィールド変数をクラス変数(静的変数)といい,クラスに関連付けられているメソッドをクラスメソッドといいます.
クラス変数はスタティック(static)という記憶クラス指定子を付けて宣言します.その構文は次のようになります.
class StaticX
{
private static int n; // nをクラス変数として宣言
}
これにより,クラス変数には,次のような2通りのアクセスの仕方が可能になります.
StaticX obj = new StaticX();
obj.n = 100;
または,
StaticX.n = 100;
class StaticField
{ private static int count = 0; public StaticField() { ++count; } public static void main(String[] args) { StaticField t = new StaticField(); StaticField u = new StaticField(); System.out.println("StaticFieldが" + t.count + "個あります"); StaticField v = new StaticField(); System.out.println("StaticFieldが" + t.count + "個あります"); } } |
実行結果
クラスメソッド(Class Methods)
クラス変数が,クラス名.フィールド変数の形で用いることができたように,メソッドにも,クラス名.メソッド名()の形で用いたほうが便利なものがあります.例えば,数学関係の処理を行うsin()メソッドがインスタンスメソッドである場合,sin()メソッドを呼び出すには,Mathクラスのオブジェクトを次のようにして生成しなければなりません.
Math m = new Math();
double d = m.sin(1.2);
この手続きは面倒です.というのも生成されたMathオブジェクトmは,sin()の計算に何の関与もしません.sin()メソッドに必要なデータはパラメターとして渡され計算結果はメソッドの戻り値として呼び出し元に返されます.クラスのインスタンスを作成したとしても,メソッドの呼び出し以外まったく必要のないものです.これを解決するため,staticキーワードを使用して,メソッドをクラスメソッドとして定義します.
クラスメソッドを呼び出すには,
クラス名.メソッド名(引数リスト);
の形をとります.
class StaticMethod
{ private static int count = 0; public StaticMethod() { ++count; } private static int num() { return count; } \hspace{1cm} public static void main(String[] args) { StaticMethod t = new StaticMethod(); StaticMethod u = new StaticMethod(); System.out.println("StaticMethodが" + StaticMethod.num() + "個あります"); StaticMethod v = new StaticMethod(); System.out.println("StaticMethodが" + StaticMethod.num() + "個あります"); } } |
実行結果
1. クラスの公開メンバと非公開メンバとの違いを説明しなさい.
2. クラスメソッドとインスタンスメソッドとの違いを説明しなさい.
3. ディフォルトコンストラクタとそれ以外のコンストラクタとの違いを説明しなさい.
4. コンストラクタにはどんな名前を付けることができるか.
6. 1つのクラスには何個のコンストラクタとディストラクタを含むことができるか.
1. 空間上の点(x,y,z)からなるPointクラスを作成しなさい.ただし,このクラスは,ディフォルトコンストラクタ,点の座標を負にするnegate()関数,距離を表すnorm()関数,そして表示のためのprint()関数を含むとします.
2. 整数のスタックのStackクラスを作成しなさい.ディフォルトコンストラクタ,ディストラクタ,push(), pop(), isEmpty(), isFull()関数を含むものとします.