課題:講義資料オブジェクト指向プログラムJavaI&IIの中のサンプルプログラムについて考察せよ。
*講義資料サンプルプログラム考察については、ローカル変数以降interface までとする。
名 前 仲松義嗣
学籍番号 035735k
所 属 工学部情報工学科
提出期限 2003/12/15
ローカル変数とクラス変数
・2つの変数の和と差の積を表示するプログラム
01:class Display {
02: int x,y; //クラス変数
03: void display() {
04: int i = x + y; //ローカル変数
05: int j = x - y; //ローカル変数
06: System.out.println(x*y);
07: }
08:}
09:
10:class Scope {
11: public static void main(String args[]) {
12: Display obj = new Display();
13: obj.x = 10; //クラス変数にアクセス
14: obj.y = 2; //クラス変数にアクセス
15: //System.out.println(obj.i); //ローカル変数にアクセス
16: obj.display();
17: }
18:}
実行結果1(15: //System.out.println(obj.i); )
j03035% javac Scope.java
j03035% java Scope
96
実行結果2(15: System.out.println(obj.i); )
j03035% javac Scope.java
Scope.java:15: cannot resolve symbol
symbol : variable i
location: class Display
System.out.println(obj.i);
^
1 error
---考察---
実行結果1と実行結果2よりあるクラスの変数に対するアクセスがその変数
をどこで宣言するかに依存することが分かります。そして、アクセス可能な変
数がクラス変数、不可能な変数がローカル変数と言われています。
static変数
・クラス変数を共有しないプログラム
01:class Conect {
02: String x;
03: Conect() { //コンストラクタ(クラス名と同名)
04: x = "Nakamatsu";
05: }
06: void add(String y) {
07: x += y;
08: }
09:}
10:
11:class Static1 {
12: public static void main(String args[]) {
13: Conect obj1 = new Conect(); //クラスConectのオブジェクトobj1生成
14: Conect obj2 = new Conect(); //クラスConectのオブジェクトobj2生成
15: obj1.add("Yoshitsugu");
16: obj2.add("kun");
17: System.out.println("obj1.x = " + obj1.x);
18: System.out.println("obj2.x = " + obj2.x);
19: }
20:}
実行結果1
j03035% java Static1
obj1.x = NakamatsuYoshitsugu
obj2.x = Nakamatsukun
・クラス変数を共有するプログラム
01:class Conect {
02: static String x; //static修飾子によるメモリ領域の共有
03: Conect() { //コンストラクタ(クラス名と同名)
04: x = "Nakamatsu";
05: }
06: void add(String y) {
07: x += y;
08: }
09:}
10:
11:class Static2 {
12: public static void main(String args[]) {
13: Conect obj1 = new Conect(); //クラスConectのオブジェクトobj1生成
14: Conect obj2 = new Conect(); //クラスConectのオブジェクトobj2生成
15: obj1.add("Yoshitsugu");
16: obj2.add("kun");
17: System.out.println("obj1.x = " + obj1.x);
18: System.out.println("obj2.x = " + obj2.x);
19: }
20:}
実行結果2
j03035% java Static2
obj1.x = NakamatsuYoshitsugukun
obj2.x = NakamatsuYoshitsugukun
---考察---
Static1の実行結果1とStatic2の実行結果2からクラス変数にstatic修飾子
を付けると、生成されたオブジェクト間でそのクラス変数が共有されることが
分かります。
ちなみに、ローカル変数にstatic変数を付けても、アクセスすらできないの
で共有はもちろんできません。
コンストラクタ
・コンストラクタのオーバーロードプログラム
01:class Conect {
02: String x;
03:
04: Conect() { //コンストラクタ 引数無し
05: x = "Nakamatsu";
06: }
07: Conect(String y) { //コンストラクタ 引数 y
08: x = y;
09: }
10:
11: void add(String z) {
12: x += z;
13: }
14:}
15:
16:class Constructer {
17: public static void main(String args[]) {
18: Conect obj1 = new Conect(); //クラスConectのオブジェクトobj1生成
19: obj1.add("Kun");
20: System.out.println("Conect1 = " + obj1.x);
21:
22: Conect obj2 = new Conect("Yoshitsugu"); //クラスConectのオブジェクトobj2生成
23: obj2.add("Kun");
24: System.out.println("Conect2 = " + obj2.x);
25: }
26:}
実行結果
j03035% java Constructer
Conect1 = NakamatsuKun
Conect2 = YoshitsuguKun
---考察---
クラス名と同じコンストラクタを違う引数で宣言すると、違うコンストラク
タと認識されていることが分かります。
つまり、18:と22:のように違う引数でコンストラクタを宣言すると全く違う
オブジェクトが生成されていると考えられます。
staticイニシャライズ
・staticイニシャライズのサンプルプログラム
01:class Calculater {
02: int x = 10;
03: int y = 5;
04:
05: static { //staticイニシャライズ
06: int x = 10;
07: int y = 5;
08: System.out.println(x + y);
09: }
10: Calculater() { //コンストラクタ
11: System.out.println(x - y);
12: }
13:}
14:
15:class StaticIn {
16: public static void main(String args[]) {
17: Calculater obj1 = new Calculater();
18: }
19:}
実行結果
j03035% java StaticIn
15
5
---考察---
mainメソッドの中では、10:で宣言したコンストラクタのオブジェクトを作っ
ただけにもかかわらず、実行結果を視ると、staticの中のメソッドがコンスト
ラクタよりも前に実行されていることが分かります。
つまり、static{}を使うことで、どのコンストラクタよりも早く処理したい
メソッドを用意できそうです。
メソッドのオーバーロード
・メソッドのオーバーロードのサンプルプログラム
01:class Display {
02: void Disp() { //0個の引数を取るメソッドDisp
03: System.out.println("Nothing");
04: }
05: void Disp(int x) { //1個の引数を取るメソッドDisp
06: System.out.println(x);
07: }
08: void Disp(int x, int y) { //2個の引数を取るメソッドDisp
09: System.out.println(x * y);
10: }
11: //int Disp(int x, int y) { //2個の引数を取るメソッドDisp
12: // return x % y;
13: //}
14:}
15:
16:class OverloadSample {
17: public static void main(String args[]) {
18: Display obj = new Display(); //クラスDisplayのオブジェクトobjの生成
19:
20: obj.Disp(); //オブジェクトobjのDisp()を実行
21: obj.Disp(1); //オブジェクトobjのDisp(1)を実行
22: obj.Disp(1,2); //オブジェクトobjのDisp(1,2)を実行
23: }
24:}
実行結果1
j03035% javac OverloadSample
j03035% java OverloadSample
1
2
実行結果2
j03035% javac OverloadSample
OverloadSample.java:11: Disp(int,int) is already defined in Display
int Disp(int x, int y) {
^
1 error
---考察---
実行結果2は11~13のコメントをはずしたものです。
実行結果1よりメソッドもコンストラクタと同様に引数の数や型を変えること
で複数個の宣言が可能であることが分かります。
また、実行結果2より引数の数や型が同じで戻り値の違うメソッドを同時に
宣言することはできませんでした。
つまり、オーバーロードは戻り値には依存していません。
アクセス制御
・
01:class keisan {
02: static int tanka;
03: private float rate; //プライベート変数rate
04:
05: keisan() {
06: tanka = 1000;
07: rate = 0.05f; //同一クラスのメソッドからアクセス
08: }
09:
10: int keisan(int kazu) {
11: int kingaku;
12:
13: kingaku = (int)(tanka * kazu * (1.0 + rate)); //同一クラスのメソッドからアクセス
14: return kingaku;
15: }
16:}
17:
18:class PrivateSample {
19: public static void main(String args[]) {
20: keisan obj1 = new keisan();
21: int kazu = 3;
22: int kingaku = obj1.keisan(kazu);
23:
24: System.out.println("tanka = " + obj1.tanka);
25: System.out.println("kazu = " + kazu);
26: System.out.println("kingaku = " + kingaku);
27: //System.out.println("rate = " + obj1.rate); //同一クラスでないクラスからのアクセス
28: }
29:}
実行結果
j03035% java PrivateSample
tanka = 1000
kazu = 3
kingaku = 3150
---考察---
27:のように同一クラスでないクラスからアクセスをしようとすると、コン
パイルを通さないようです。
継承
・継承のサンプルプログラム
01:class Display { //スーパークラスDisplay
02: void Disp() { //スーパークラスのメソッドDisp
03: System.out.println("Happy?");
04: }
05:}
06:
07:class Succeed extends Display { //スーパークラスDisplayを継承したサブクラスSucceed
08: public static void main(String args[]) { //サブクラスのmainメソッド
09: Succeed obj = new Succeed(); //オブジェクトの生成
10: obj.Disp(); //スーパークラスから継承したメソッドの利用
11: }
12:}
実行結果1
j03035% java Succeed
Happy?
・複数のファイルを継承を利用してリンクさせるサンプルプログラム
スーパークラス
01:class Display { //スーパークラスDisplay
02: void Disp() { //スーパークラスのメソッドDisp
03: System.out.println("Happy?");
04: }
05:}
サブクラス
01:class Override extends Display {
02: void Disp() { //スーパークラスのメソッドDispをオーバーライド
03: System.out.println("Are you happy?");
04: }
05:
06: public static void main(String args[]) { //サブクラスのmainメソッド
07: Override obj = new Override(); //オブジェクトの生成
08: obj.Disp(); //オーバーライドしたメソッドDispの実行
09: }
10:}
実行結果2
j03035% java Succeed
Are you happy?
・オーバーライドの位置を確認するプログラム
スーパークラス
01:class Display { //スーパークラスDisplay
02: void Disp() { //スーパークラスのメソッドDisp
03: System.out.println("Happy?");
04: }
05:}
サブクラス
01:class Override extends Display {
02: public static void main(String args[]) { //サブクラスのmainメソッド
03: Override obj = new Override();
04: obj.Disp();
05:
06: void Disp() { //オーバーライドする位置の確認
07: System.out.println("Are you happy?");
08: }
09: }
10:}
実行結果3
j03035% javac Override.java
Override.java:6: illegal start of expression
void Disp() {
^
Override.java:8: ';' expected
}
^
2 errors
---考察---
実行結果2より継承することでファイルをつなげることができることが分か
ります。これにより、オブジェクト指向が高まり、再利用し易くなりそうです。
また、実行結果3よりオーバーライドの位置はmainメソッドの外である必要
がありそうです。
super
・スーパークラスのメソッドを呼び出す
01:class Display {
02: void Disp() {
03: System.out.println("Hello!");
04: }
05:}
06:
07:class SuperSample extends Display {
08: void Disp() {
09: super.Disp();
10: System.out.println("Hello! Java!!");
11: }
12: public static void main(String args[]) {
13: SuperSample obj = new SuperSample();
14: obj.Disp();
15: }
16:}
実行結果1
j03035% java SuperSample
Hello!
Hello! Java!!
・スーパークラスのフィールドを呼び出す
01:class Display {
02: int i = 2;
03: void Disp() {
04: System.out.println(i);
05: }
06:}
07:
08:class SuperSample1 extends Display {
09: void Disp() {
10: super.i = 5;
11: System.out.println(i);
12: }
13: public static void main(String args[]) {
14: SuperSample obj = new SuperSample();
15: obj.Disp();
16: }
17:}
実行結果2
j03035% java SuperSample1
5
---考察---
実行結果1と実行結果2よりスーパークラスのメソッドだけでなく、フィー
ルドを呼び出すこともできることが分かります。
this
・カレントクラスのフィールドを呼び出す
01:class Keisan {
02: int x = 100;
03: void add(int x, int y) { //メソッドaddの生成
04: int w1 = x + y;
05: int w2 = this.x + y; //this.xがカレントクラスのx
06: System.out.println("w1 = " + w1 + " w2 = " + w2);
07: }
08:}
09:
10:class ThisSample1 {
11: public static void main(String args[]) {
12: Keisan obj = new ThisSample1();
13: obj.add(10, 20); //メソッドaddの実行
14: }
15:}
実行結果1
j03035% java ThisSample1
w1 = 30 w2 = 120
・カレントクラスのメソッドを呼び出す
01:class Keisan {
02: public Keisan(int x,int y) { //引数が2つのメソッド
03: System.out.println("Keisan = " + (x * y));
04: }
05: public Keisan(int x) { //引数が1つのメソッド
06: this(x, 1); //カレントクラスのメソッドを利用
07: }
08:}
09:
10:class ThisSample2 {
11: public static void main(String args[]) {
12: Keisan obj1 = new Keisan(200,5); //引数が2つのメソッドを実行
13: Keisan obj2 = new Keisan(200); //引数が1つのメソッドを実行
14: }
15:}
実行結果2
j03035% java ThisSample2
Keisan = 1000
Keisan = 200
---考察---
実行結果1は05:でカレントクラスのフィールドを呼び出しています。
実行結果2は06:でカレントクラスのメソッドを呼び出しています。
abstract
・抽象クラス
01:public abstract class PreDefine {
02: public abstract int add(int x,int y); //抽象メソッド
03: public int sub(int x,int y) { //メソッド
04: return x - y;
05: }
06:}
・抽象クラスを継承するクラス
01:class AbstractSample extends PreDefine {
02: public int add(int x, int y) { //抽象メソッドを実装
03: return x + y;
04: }
05:
06: public static void main(String args[]) {
07: AbstractSample obj = new AbstractSample();
08: System.out.println("add = " + obj.add(100,80)); //抽象メソッドの実行
09: System.out.println("sub = " + obj.sub(100,80));
10: }
11:}
実行結果
j03035% java AbstractSample
add = 180
sub = 20
---考察---
ファイルを区別することで開発を効率よく進めることができそうです。
interface
・インターフェイス
01:public interface PreDefine {
02: int add(int x,int y); //抽象メソッドadd
03: int sub(int x,int y); //抽象メソッドsub
04:}
・実行クラス
01:class InterfaceSample implements PreDefine {
02: public int add(int x,int y) { //抽象メソッドの実装
03: return x + y;
04: }
05: public int sub(int x,int y) { //抽象メソッドの実装
06: return x - y;
07: }
08:
09: public static void main(String args[]) {
10: InterfaceSample obj = new InterfaceSample();
11: System.out.println("add = " + obj.add(100,80));
12: System.out.println("sub = " + obj.sub(100,80));
13: }
14:}
実行結果
j03035% java InterfaceSample
add = 180
sub = 20
---考察---
インタフェースは抽象クラスと違い、抽象メソッドのみからできています。
上のプログラムはインターフェイスに足し算をするaddメソッドと引き算をす
るsubメソッドの抽象メソッドを定義しています。
実行クラス内で抽象クラスの実装をして、実行します。
感想・反省
今回はHTMLの記述にもこだわってみました。
参考URL http://www.osnr.net/taniguchi/lecture/java/obj01.html
http://www.osnr.net/taniguchi/lecture/java/obj02.html