ソフト ウェア演習
C目 次
第
8
章
Java (3) |
クラスとメソッド
1
8.1
第
8
回演習内容
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :1
8.2
クラス
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :1
8.2.1
クラスの定義
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :1
8.2.2
フィールド の定義
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :2
8.2.3
コンストラクタ
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :2
8.2.4
メソッド
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :3
8.3
インスタンスの生成
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :6
8.4
サンプルプログラム
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :7
8.5
課題
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :11
第
8章
Java (3) |クラスとメソッド
8.1第
8回演習内容
Java
を用いてプログラムを作成する場合、プログラミングの主な作業はクラスの定義に費やされると言
われるほど クラスの定義は非常に重要な部分です。
今回の演習では、このクラスの定義と使用方法についての演習を行います。
第
8
回目の演習内容は以下の通りです。
クラスの定義
フィールド
コンストラクタ
メソッド
インスタンスの生成
8.2クラス
クラスは、変数(フィールド )やメソッド などから構成されています。
8.2.1クラスの定義
クラスを宣言するためには、
class
という予約語を用います。また、
class
の後に定義するクラスの名
前を記述します。具体的なクラスの中身は
\
{
"
と
\
}
"
の中に記述します。したがって、クラスの定義は以
下のようになります。
<
クラス修飾子
>
class
クラス名
{
<
フィールド の定義
>
<
コンストラクタの定義
>
<
メソッド の定義
>
}
クラス修飾子
(modier)
はクラスの性質を規定するためのものです。次の三つのうちのいずれかを
class
の前に記述し 、宣言することができます。
abstract
...
このクラスは、
abstract
クラスと呼ばれ、インスタンスを生成することができません。
final
...
このクラスは、
final
クラスと呼ばれ 、サブ クラスを作成することができません。
public
...
このクラスは、
public
クラスと呼ばれ 、他の任意のクラスからアクセスすることがで
きます。
これらの指定がないクラスは同一デ ィレクトリ内でのみアクセス可能となります。
クラスの定義では、フィールド の定義、コンストラクタの定義、メソッド の定義が主な作業です。それ
ぞれを次の節から説明します。
8.2.2フィールド の定義
クラス内で宣言される変数のうち、メソッド の外で宣言される変数はフィールド といいます。フィール
ド の定義は変数の宣言と似ています。
フィールド の定義書式は以下のようになります。
<
変数修飾子
>
型名 変数名
<=
式
>
;
ここで、以下のような変数修飾子を使用することにより、クラス修飾子と同様に、変数へのアクセスを制
御することができます。
public
...
この変数には、そのクラスにアクセスできる他のすべてからアクセスできます。
protected
...
この変数には、そのクラス自身とそのサブクラスからのみアクセスできます。
private
...
この変数には、そのクラス自身からのみアクセスできます。
これらの指定がない変数は同一デ ィレクトリ内でのみアクセス可能となります。
たとえば 、以下のようになります。
int x
//
通常の宣言
public int y
//
どこからでもアクセスできる
protected int r
//
このクラスとサブ クラスのみアクセスできる
private double c
//
このクラスのみアクセスできる
Graphics gc
// Graphics
クラスのオブジェクト
public JFrame myframe // myframe
オブジェクトを
public
アクセスに宣言
さらに 、上のような宣言に加え、
static
を宣言することにより、その変数はクラスフィールド
(class
eld)
となり、インスタンスではなく、クラス自身に割り付けられます。つまり、この変数はクラスに対
して
1
つだけ存在し 、そこから生成されるすべてのインスタンスで共有できます
1。
たとえば 、以下のようになります。
static int ] data = {9, 7, 6}
//
クラスフィールド
public static double E=2.7182
8.2.3
コンスト ラクタ
コンスト ラクタ
(constructor)
は、クラス名と同じ名前のメソッド です。コンストラクタにより、オブ
ジェクトは初期化されます。オブジェクトの初期化とはメモリ割当て、変数のデフォルト値の代入、他の
コンストラクタの呼び出し等のことです。
1 注意:フィールドはメソッド の外に定義しなければなりません。変数はメソッド の中に宣言すれば 、そのメソッド の中だけ有効 です。クラス定義にコンストラクタがない場合には、プログラムをコンパイルする時に自動的にデフォルト コ
ンスト ラクタが生成されます。
Java
のコンパイラが確認します。
8.2.4メソッド
メソッド の定義
メソッド
(method)
は
C
言語における関数に相当します。メソッド の定義は関数の形
(
必要な変数を宣
言したり、必要な制御構造を記述する等のこと )で扱われます。メソッドの宣言は、メソッドの型、メソッ
ド 名、引数のリスト、メソッド 本体を指定することにより次のように記述します。
<修飾子> メソッド の型 メソッド 名(引数) { メソッド の定義 return(式) }ここで、
引数はメソッドに渡されるデータです。なお、複数の引数がある場合はカンマで区切られます。ま
た、引数のないメソッド を定義することもできます。
return
文の式は、メソッド の返す値です。
void
型
のメソッド では、メソッド の型は
void
となり、
(
式
)
の部分が省略されます。コンストラクタの定義にも
戻り値の文は書きません。また、修飾子は、クラスや変数の場合と同様にメソッド のアクセス制御を指定
します。メソッド 修飾子は
public
,
protected
,
private
があります。 修飾子は省略可能です。省略時は
同一クラス内からのみアクセスが可能となります。
メソッドは、上のような宣言に
static
指定を加えて定義することができます。これを静的メソッド
(static
method)
あるいはクラスメソッド
(class method)
と呼びます。
static
指定により、メソッド はオブ
ジェクトを生成しなくともアクセス可能となります。
メソッド の呼び出し
オブジェクトは、クラス内で定義されているメソッド を呼び出すことによって、様々な処理をおこなう
ことが出来ます。
Java
のメソッド 呼び出しは、以下の通りです ( なお、クラス名はインスタンス名でも
良いです)
。
クラス名
.
メソッド 名
(
引数
)
オーバロード
Java
では 、引数の内容が異なり、同一の名前を持つコンストラクタおよび メソッド の存在を許してい
ます。
複数コンストラクタやメソッド を定義することをオーバーロード
(Overload)
と呼びます。
例えば 、以下のように、引数の異なる2つのコンストラクタを定義できます。
// Rectangle.java public class Rectangle {
protected double width, height // フィールド の定義
public Rectangle(double w, double h) { // コンストラクタ1 width = w height = h } public Rectangle() { // コンストラクタ2 width = 3 height = 3 } // メソッド の定義
double area() { // メソッドarea() return width*height
}
public double circumference() { // メソッドcircumference() return 2*(width + height)
}
public static void main(String ] args){ // メソッド main() Rectangle r1 = new Rectangle(10,5)
System.out.println("Rectangle 1:") System.out.println("width is " + r1.width) System.out.println("height is " + r1.height) System.out.println("area is " + r1.area()) System.out.println("circumference is " + r1.circumference()) System.out.println("---") System.out.println("Rectangle 2:") Rectangle r2 = new Rectangle()
System.out.println("width is " + r2.width) System.out.println("height is " + r2.height) System.out.println("area is " + r2.area()) System.out.println("circumference is " + r2.circumference()) } }
このプログラムでは、
double
型の
2
つの引数を持つコンストラクタと、引数を持たないコンストラクタ
の
2
つを定義しています。これにより、引数のあるなしにより処理を分けることができるのです。
プログラムを保存するファイル名は、
Rectangle.java
とし ます。そのプログラムを実行すると、以下の
ような結果を得ます。
$ javac Recatngle.java $ java Rectangle Rectangle 1: width is 10.0 height is 5.0 area is 50.0 circumference is 30.0 ---Rectangle 2: width is 3.0 height is 3.0 area is 9.0 circumference is 12.0演習
8-1以下の条件を満たす円
(
Circle
)
クラスを作成せよ。円は中心座標
x,y
と半径
r
をフィールド として持
つ。また、円周の長さと面積を計算するメソッド、および指定座標分だけ中心を移動するメソッドを持つ。
さらに、中心座標と半径を引数とするコンストラクタも
1
つ持つ。
main()
メソッドで円クラスのオブジェ
クト
(
x=10, y=5, r=4
)
を
1
つ作成し 、その円周の長さと面積を計算せよ。また、現在の中心座標から、
x
方向へ
7
、
y
方向へ
10
だけ移動した場合の中心座標を計算せよ。
再帰メソッド
メソッドが自分自身を呼び出すことは
Java
にもできます。
再帰呼出を用いた階乗を計算するメソッド を作ってみましょう。階乗
x!
は次のように再帰的に定義され
ます。
0! = 1
x! =
x(
x;1)!
この定義により再帰呼び出しを行う階乗計算メソッド を次のプログラムように作ることができます。
// Factorial.java class Factorial {public static void main(String ] args) { int n = 10
System.out.println("n = " + n)
System.out.println("Factorial(" + n +")=" + fact(n)) }
public static int fact(int n) { // 再帰呼出
if (n==0) { return(1) } else { return(n * fact(n-1)) } } }
プログラムを保存するファイル名は、
Factorial.java
とし ます。そのプログラムを実行すると、以下の
ような結果を得ます。
$ javac Factorial.java $ java Factorial n = 10 Factorial(10)=3628800ここで、
fact(int n)
関数はクラスメソッド として定義しています。インスタンスを生成することなく
呼び出すことができます。
演習
8.2次の配列をソートするプログラムを、クイックソートを使用して作成せよ。クイックソートはクラスメ
ソッド と再帰呼出メソッド として実装する( クイックソートについては、ソフトウェア演習
B
の第
8
回の
テキストを参考にすること
)
。
1,6,15,12,7,9,23,2,10,4,20]
8.3インスタンスの生成
Java
の第
1
回で説明しましたが 、オブジェクトはクラスのインスタンスです。クラスを参考にしてオブ
ジェクトが生成されることになります。逆に言えば 、オブジェクトはどれかのクラスに属していなければ
なりません。
インスタンスの生成は 通常は
new
を用いるとともに、クラス名、インスタンス名および引数を指定して、
クラス名
変数名
変数名
= new
コンストラクタ名
(
引数
)
のように記述することにより行われます。
なお、この記述は次のように書くこともできます。
クラス名
変数名
= new
コンストラクタ名
(
引数
)
たとえば 、次のような形で記述します。
// MyObjects.java import java.util.Date class MyObjects {public static void main(String ] args) { Date d
d = new Date()
System.out.println("Date : " + d) Rectangle r = new Rectangle(30,40)
System.out.print("My rectangle is "+ r.width + "cm x ") System.out.print(r.height + "cm area=" + r.area() + "cm^2 ") System.out.println("circumference=" + r.circumference() + "cm") String firstname = new String("Ichiro")
String lastname lastname = "Suzuki"
System.out.println("Object Name : " + firstname + " " + lastname) } }
生成されたオブジェクトはプログラムを終了した後に削除する必要はありません。
プログラムを保存するファイル名は、
MyObjects.java
とし ます。そのプログラムを実行すると、以下の
ような結果を得ます。
$ javac MyObjects.java $ java MyObjects
Now Date : Thu May 31 19:38:45 JST 2001
My rectangle is 30.0cm x 40.0cm area=1200.0cm^2 circumference=140.0cm Object Name : Ichiro Suzuki
8.4
サンプルプログラム
ここでは、第
6
回演習の必須課題
1-(a)
で考えたようなスタック
(Stack)
クラスを作成します
(
図
8.1)
。
基本的にスタッククラスは配列変数と
push/pop
メソッド を持ちます。
push
は配列の末尾へ要素を
1
つ追
加するメソッド で、
pop
は配列の末尾から要素を
1
つ取り出すメソッド です。なお、この例では、配列の
要素は文字列としています。
push(String)
String pop()
count = 2
capacity = 5
itemList = String[capacity]
"Nobu"
"Kenji"
capacityIncrement
図
8.1:
スタックのオブジェクト
// Stack.java public class Stack {
// フィールド の定義
private int count // スタックのアイテム数
private int capacity // スタックの配列の数量
private int capacityIncrement // 配列のサイズを増やす
String ] itemList // スタックの配列 // 引数無のコンストラクタの定義 public Stack() { count = 0 capacity = 5 capacityIncrement = 2
itemList = new Stringcapacity] }
// リスト引数を持つコンストラクタの定義
public Stack(String ] list) { count = list.length capacity = list.length capacityIncrement = 5 itemList = list } // push メソッド の定義
public void push (String obj){
// スタックの配列の数量が足りない場合は
// capacityIncrement増やす
if (count == capacity) {
capacity += capacityIncrement
String ] tempList = new Stringcapacity] for (int i = 0 i < count i++){
tempListi]=itemListi] } itemList = tempList } // スタックリストの末尾に要素を挿入 // countは1を増やす itemListcount] = obj count++ } // 戻る値 pop メソッド の定義
public String pop (){
if (count == 0){ // スタックを空ならば 、 return null // ヌルオブジェクトを戻す. } else { // そうでなければ count-- // スタックの数を減らす return itemListcount] // トップのオブジェクトを戻す } } // end pop()
(
次のページへつづく
)
// スタックの内容を表示
public void printItems(){ for (int i=0i < counti++){
System.out.print(itemListi] + ",") } System.out.println(" ") } } // スタッククラスを終了 // ファイル Stack.java を終了 // StackTest.java public class StackTest {
public static void main (String ] args) { String ] items = {"Kenji","Nobu"}
Stack mystack = new Stack(items) // mystack インスタンスを生成
System.out.println("Initial data :")
mystack.printItems() // mystack の配列を表示
System.out.println(" ")
System.out.println("---")
mystack.push("Taro") // 新要素を付け加える
System.out.println("Data after push Taro :") mystack.printItems()
System.out.println(" ")
System.out.println("---")
String popObject1 = mystack.pop() // 要素を取り除く
System.out.println("Data after pop object " + popObject1 + " :") mystack.printItems()
System.out.println(" ")
System.out.println("---") String popObject2 = mystack.pop()
System.out.println("Data after pop object " + popObject2 + " :") mystack.printItems() System.out.println(" ") System.out.println("---") } }
このプログラムを実行すると以下のような結果が得られます。なお、ここでは、
StackTest.java
をコン
パイルすると、自動的に
Stack.java
もコンパイルされます。
$ javac StackTest.java $ java StackTest Initial data : Kenji,Nobu,
---Data after push Taro : Kenji,Nobu,Taro,
---Data after pop object Taro : Kenji,Nobu,
---Data after pop object Nobu : Kenji, ---
演習
8-3キュー
(Queue)
はスタックのように 、配列変数と
push/shift
メソッド から構成される。スタックク
ラスを参考に、キュークラスを作成せよ。また、作成したキュークラスを利用し 、
Komachi, Yamabiko,
8.5
課題
必須課題については必ずレポートを提出してください。自由課題にもぜひ挑戦してみましょう。
2必須課題
1.
以下の条件を満たす円
(
Circle
)
クラスを作成せよ。円は中心座標
x,y
と半径
r
をフィールド として
持つ。また、円周の長さと面積を計算するメソッド、および指定座標分だけ中心を移動するメソッド
を持つ。さらに、中心座標と半径を引数とするコンストラクタも
1
つ持つ。
main()
メソッドで円クラ
スのオブジェクト
(
x=10, y=5, r=4
)
を
1
つ作成し 、その円周の長さと面積を計算せよ。また、現在
の中心座標から、
x
方向へ
7
、
y
方向へ
10
だけ移動した場合の中心座標を計算せよ。
2.
次の配列をソートするプログラムを、クイックソートを使用して作成せよ。クイックソートはクラス
メソッド と再帰呼出メソッド として実装する( クイックソートについては、ソフトウェア演習
B
の第
8
回のテキストを参考にすること )
。
1,6,15,12,7,9,23,2,10,4,20]
3.
キュー
(Queue)
はスタックのように、配列変数と
push/shift
メソッドから構成される。スタッククラ
スを参考に、キュークラスを作成せよ。また、作成したキュークラスを利用し 、
Komachi, Yamabiko,
Tsubasa, Nasuno
を追加し 、その後
Komachi, Yamabiko
を取り出すプログラムを作成せよ。
2
自由課題
1.
線形連結リストのクラスを作成せよ。このクラスは、セル変数、セル挿入メソッド、セル削除メソッ
ド から構成されるものとする。セルは以下のようなクラスを定義する。
// Cell.java public class Cell {
int item // ここではセルの要素は整数 Cell next }