課題
Report#5:講義資料オブジェクト指向プログラムJavaI&IIの中のサンプルプログラムについて考察せよ。
ローカル変数とクラス変数
プログラム例----------------------------------------------------------------
int n ; // クラス変数
void Disp() {
int i; // ローカル変数
for (i = 1; i <= n; i++)
System.out.print(i + " ");
}
void Disp2() {
int i; // ローカル変数
for (i = 3; i <= n; i++)
System.out.print(i + " ");
}
}
class VarSample {
public static void main(String args[]) {
Display obj = new Display(); // クラスDisplayのオブジェクトobj生成
obj.n = 10; // オブジェクトobjの変数nに10を代入
obj.Disp(); // オブジェクトobjのDisp()実行
obj.Disp2(); //オブジェクトobjのDisp2()実行
}
}
実行結果----------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 3 4 5 6 7 8 9 10
考察
クラス変数?・・・・メソッドの外部で宣言した変数で各メソッドでも共通して使える。
ローカル変数・・・・メソッドの内部で宣言した変数。宣言したメソッド内でしか使えない。メソッドが呼び出されるたびに初期化される。
実行結果から初めDispメソッドが実行されて、次にDisp2メソッドが実行されている。
static変数
プログラム例------------------------------------------------------------------
class Sum {
int total;
Sum() { // コンストラクタ(クラス名と同名)
total = 0; // 0 クリア
}
void add(int x) {
total += x;
}
}
class SumSample {
public static void main(String args[]) {
Sum obj1 = new Sum(); // クラスSumのオブジェクトobj1生成
Sum obj2 = new Sum(); // クラスSumのオブジェクトobj2生成
obj1.add(10);
obj1.add(20);
obj2.add(30);
obj2.add(40);
System.out.println("obj1.total = " + obj1.total);
System.out.println("obj2.total = " + obj2.total);
}
}
実行結果-----------------------------------------------------------------------
obj1.total = 30
obj2.total = 70
考察
obj1とobj2のtotalは別
staticを用いて値を共有するプログラム例-----------------------------------------
class Sum {
static int total; // 値を共有させる
Sum() { // コンストラクタ(クラス名と同名)
total = 0; // 0 クリア
}
void add(int x) {
total += x;
}
}
class SumSample {
public static void main(String args[]) {
Sum obj1 = new Sum(); // クラスSumのオブジェクトobj1生成
Sum obj2 = new Sum(); // クラスSumのオブジェクトobj2生成
obj1.add(10);
obj1.add(20);
obj2.add(30);
obj2.add(40);
System.out.println("obj1.total = " + obj1.total);
System.out.println("obj2.total = " + obj2.total);
}
}
実行結果-----------------------------------------------------------------------
obj1.total = 100
obj2.total = 100
考察
static・・・・クラス変数、クラスメソッドにつける
クラス変数・・・・クラス全体で扱うデータを格納しておくフィールド。クラス変数は各オブジェクトから共有される。
2つのプログラムを比べると、はじめのプログラムはobj1とobj2の値が別だが、2つ目のプログラムはobj1とobj2の値が共有されている。
コンストラクタ
コンストラクタを用いた合計プログラム例 ----------------------------------------
class Sum {
int total;
Sum() { // コンストラクタ 引数無し
total = 0;
}
Sum(int x) { // コンストラクタ 引数 x
total = x;
}
void add(int x) {
total += x;
}
}
class ConstrcSample {
public static void main(String args[]) {
Sum obj1 = new Sum(); // クラスSumのオブジェクトobj1生成
obj1.add(10);
obj1.add(20);
System.out.println("sum1 = " + obj1.total);
Sum obj2 = new Sum(100); // クラスSumのオブジェクトobj2生成。引数100を代入
obj2.add(10);
obj2.add(20);
System.out.println("sum2 = " + obj2.total);
}
}
実行結果-----------------------------------------------------------------------
sum1 = 30
sum2 = 130
考察
コンストラクタ・・・・メソッドとたいへんよく似ているがコンストラクタの名前はクラス名と同じでなければならない。また戻り値は指定できない。そのクラスのオブジェクトが作成されたときに、定義しておいたコンストラクタ内の処理が自動的に行われる。
staticイニシャライズ
staticイニシャライズを行ったプログラム例---------------------------------------
class Disp {
static { // static イニシャライズ
System.out.println("initialize");
}
Disp() { // コンストラクタ
System.out.println("construct");
}
}
class StaticSample {
public static void main(String args[]) {
Disp obj1 = new Disp(); // オブジェクト生成時にコンストラクタを処理
Disp obj2 = new Disp(); // オブジェクト生成時にコンストラクタを処理
}
}
実行結果-----------------------------------------------------------------------
initialize ※ Dispクラスのロード時に処理
construct ※ Disp.obj1 = new Disp(); が実行されるときに処理
construct ※ Disp.obj2 = new Disp(); が実行されるときに処理
考察
staticイニシャライズ・・・・クラスが呼ばれた時に1度だけ実行される。コンストラクタよりも早い。
実行結果よりobj1のコンストラクタよりも早く実行されている。また1度だけしか処理されないのでobj2のときは行われていないことが分かる。
メソッドのオーバーロード
メソッドのオーバーロードを行ったプログラム例-----------------------------------
class Display {
void Disp() { // メソッド Disp 引数なし
System.out.println("Nothing");
}
void Disp(int x) { // メソッド Disp 引数 x
System.out.println(x);
}
void Disp(int x, int y) { // メソッド Disp 引数 x, y
System.out.println(x + y);
}
}
class OvldSample {
public static void main(String args[]) {
Display obj = new Display(); // クラスDisplayのオブジェクトobj生成
obj.Disp(); // オブジェクトobjのDisp()を実行
obj.Disp(1); // オブジェクトobjのDisp(1)を実行
obj.Disp(1, 2); // オブジェクトobjのDisp(1,2)を実行
}
}
実行結果-----------------------------------------------------------------------
Noting
1
3
考察
オーバーロード・・・・同じクラスの中に、同じ名前を持つメソッドを2つ以上定義することができる。ただし各メソッドの引数の型、個数が異なるようにしなければならない。
実行結果より、引数を入れずに実行すると引数を持たないメソッドが実行され、1つ入れると引数を1つ持つメソッドが実行され、2つ入れると引数を2つ持つメソッドが実行されている。
アクセス制御
privateを用いて、変数の参照を不可にするプログラム例----------------------------
class keisan {
static int tanka;
private float rate; // private変数rateの宣言
keisan() { // コンストラクタ
tanka = 1000;
rate = 0.05f;
}
int keisan(int kazu) {
int kingaku;
kingaku = (int)(tanka * kazu * (1.0 + rate));
return kingaku;
}
}
class PrvSample {
public static void main(String args[]) {
keisan obj1 = new keisan();
int kazu = 3;
int kingaku = obj1.keisan(kazu);
System.out.println("tanka = " + obj1.tanka);
System.out.println("kazu = " + kazu);
System.out.println("kingaku = " + kingaku);
// System.out.println("rate = " + obj1.rate); //private変数のため参照不可
}
}
実行結果-----------------------------------------------------------------------
tanka = 1000
kazu = 3
kingaku = 3150
考察
private・・・・コンストラクタにつけるとクラスの外でそのコンストラクタが呼び出されるようなオブジェクトの作成ができなくなる。
プログラムの//(コメント)を外すとエラーが出ることから、privateをつけるとそのクラス外ではオブジェクトにしても使うことは出来ない。
継承
プログラム例-------------------------------------------------------------------
class Display { // スーパークラス Display
void Disp() { // メソッド
System.out.println("Hello!");
}
}
class Succeed extends Display { // スーパークラス Displayを継承したサブクラス Succeed
public static void main(String args[]) { // メソッド
Succeed obj = new Succeed(); // オブジェクト生成
obj.Disp(); // スーパークラスから継承したメソッドを利用
}
}
実行結果-----------------------------------------------------------------------
Hello!
考察
継承・・・・新しく拡張したクラスが既存のクラスのメンバを受け継ぐことを言う。
既存のクラス・・・・スーパークラス
新しいクラス・・・・サブクラス
サブクラスの宣言方法・・・・class サブクラス extends スーパークラス
実行結果よりサブクラスのSucceedにはHelloは無いが、スーパークラスのDisplayから継承して表示している。
プログラム例-------------------------------------------------------------------
class Display { // スーパークラス Display
void Disp() { // メソッド
System.out.println("Hello!");
}
}
class Override extends Display { // サブクラス Override
void Disp() { // メソッドのオーバーライド
System.out.println("Hello! Java!!");
}
public static void main(String args[]) { // メソッド
Override obj = new Override(); // オブジェクト生成
obj.Disp(); // メソッド Disp 実行
}
}
実行結果-----------------------------------------------------------------------
Hello! Java!!
考察
サブクラスOverrideにスーパークラスDisplayと同じメソッドDispをつくりオーバーライドすることができる。後で定義したほうが優先される。
super
プログラム例-------------------------------------------------------------------
class Display { // スーパークラス Display
void Disp() { // メソッド
System.out.println("Hello!");
}
}
class SuperSample extends Display { // サブクラス SuperSample
void Disp() { // メソッドのオーバーライド
super.Disp(); // スーパークラスの Disp 実行
System.out.println("Hello! Java!!");
}
public static void main(String args[]) { // メソッド
SuperSample obj = new SuperSample(); // オブジェクト生成
obj.Disp(); // サブクラスの Disp 実行
}
}
実行結果-----------------------------------------------------------------------
Hello!
Hello! Java!!
考察
super・・・・サブクラスでオーバーライトしたメソッドを呼び出すときに、オーバーライドされたスーパークラスのメソッドを呼び出す。
this
プログラム例-------------------------------------------------------------------
class Keisan { // スーパークラス Keisan
int x = 100;
void add(int x, int y) { // メソッド
int w1 = x + y;
int w2 = this.x + y;
System.out.println("w1 = " + w1 + " w2 = " + w2);
}
}
class ThisSample1 extends Display { // サブクラス ThisSample1
public static void main(String args[]) { // メソッド
ThisSample1 obj = new ThisSample1(); // オブジェクト生成
obj.add(10, 20); // add 実行
}
}
実行結果-----------------------------------------------------------------------
w1 = 30 w2 = 120
考察
this・・・・このプログラムでthisはクラス変数と同じクラス内のメソッド変数が同じ名前のときにクラス変数につけて区別するために使われている。
thisを使わなかったらメソッド変数のxが使われていることがプログラムより分かる。
プログラム例-------------------------------------------------------------------
class Keisan {
void Keisan(int x, int y) { // 引数が二つのコンストラクタ
System.out.println("Keisan = " + (x * y));
}
void Keisan(int x) { // 引数が一つのコンストラクタ
this(x, 1); // Keisan(x, 1)と同じ
}
}
class ThisSample2 extends Display { // サブクラス ThisSample2
public static void main(String args[]) { // メソッド
Keisan obj1 = new Keisan(200, 5); // 引数が二つのコンストラクタ実行
Keisan obj2 = new Keisan(200); // 引数が一つのコンストラクタ実行
}
}
実行結果-----------------------------------------------------------------------
Keisan = 1000
Keisan = 200
考察
引数が2つと1つのコンストラクタをつくり、2つのコンストラクタには、クラス変数x,yをつくりx,yを足す。引数が1つのコンストラクタは、xをつくり計算は、引数が2つのコンストラクタのyに1を代入し、後は引数が2つのコンストラクタと同じ計算をする。
abstract
プログラム例-------------------------------------------------------------------
public abstract class PreDefine { // 抽象クラス PreDefine
public abstract int add(int x, int y); // 抽象メソッド add
public int sub(int x, int y) { // メソッド sub
return x - y;
}
}
class AbstractSample extends PreDefine { // 抽象クラス PreDefine の継承
public int add(int x, int y) { // メソッドの内容を具体的に定義
return x + y;
}
public static void main(String args[]) { // メソッド
AbstractSample obj = new AbstractSample();
System.out.println("add = " + obj.add(100, 80));
System.out.println("sub = " + obj.sub(100, 80));
}
}
実行結果-----------------------------------------------------------------------
add = 180
sub = 20
考察
abstract・・・・クラス、メソッド宣言時に付けて、抽象クラス、抽象メソッドを宣言する。抽象クラスはオブジェクト
を生成することが出来ず、抽象メソッドと抽象メソッドでないメソッドを生成できる。
抽象メソッドは実装がなくサブクラスで継承して実装してオブジェクトを生成する形をとる。
プログラムのaddメソッドが抽象メソッドでAbstractSampleに継承して、抽象メソッドaddを実装し、AbstractSampleをオブジェクトにして実行している。
interface
プログラム例-------------------------------------------------------------------
public interface PreDefine { // インタフェース PreDefine
int add(int x, int y); // 抽象メソッド add
int sub(int x, int y); // 抽象メソッド sub
}
class InterfaceSample implement PreDefine { // PreDefine のインプリメント
public int add(int x, int y) { // メソッドの内容を具体的に定義
return x + y;
}
public int sub(int x, int y) { // メソッドの内容を具体的に定義
return x + y;
}
public static void main(String args[]) { // メソッド
InterfaceSample obj = new InterfaceSample();
System.out.println("add = " + obj.add(100, 80));
System.out.println("sub = " + obj.sub(100, 80));
}
}
実行結果-----------------------------------------------------------------------
add = 180
sub = 20
考察
interface・・・・インターフェイスの宣言をする。インターフェイスとはabstractと似ているが、インターフェイスは抽象メソッドしか定義できない。また複数実装することができ、実装したクラスとの間にクラス関係を意識する必要が無い。
反省・感想
このレポートは英語のテストと重なりとても大変だった。内容もこれでいいのか自信がないがやっているところは理解できたと思う。
参考文献
やさしいjava
http://www2s.biglobe.ne.jp/~yuuki_ki/