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

プログラミング言語3

N/A
N/A
Protected

Academic year: 2021

シェア "プログラミング言語3"

Copied!
23
0
0

読み込み中.... (全文を見る)

全文

(1)

1

プログラミング言語 3

05

回(

2007

10

22

日)

2/33

今日の配布物

片面の用紙

1

今日の課題が書かれています。

本日の出欠を兼ねています

(2)

3/33

今日やること

http://www.tnlab.ice.uec.ac.jp/~s-okubo/class/java06/

にアクセスすると、教材があります。

20071022日分と書いてある部分が、本日の教材です。

本日の内容

クラスとインストラクタ(再復習)

前回の課題の解答

継承

サブクラスの書き方

オーバーライド

4/33

誤植:クラスの書き方

class Test {

}

class Test {

}

必要なら修飾子を書く(クラスの修飾子については次回以降)

class名を書く

int test01;

コンストラクタを書く。今日の話の後半 で説明。

public void push(int test03){

System.out.println(test01 + test03);

}

変数を宣言する

メソッドを書く。

classと書く

変数やメソッドを

クラスのメンバと言います 必要なら

staticと書く。

(3)

5/33

オブジェクト指向プログラミング

(再復習)

6/33

設計図の世界

概念とか設計図の世界

Test

int contents;

• pushContents();

static int st_cont;

• static cont();

クラスは、設計図。

実物を作ったときに、どう いう仕様かを書いている。

設計図は、あくまでも設計図。

値を蓄えたり、メソッドを実行 したりはできない。

(4)

7/33

実物の世界も考えると...

概念とか設計図の世界 実物(オブジェクト)の世界

Test

int contents;

• pushContents();

static int st_cont;

Test.st_cont=10;

• static cont();

• Test. cont(); クラス名.メンバ名でアクセスする。

今回は、Test.st_cont の様にする。

クラスでstaticが含まれている 変数とメソッドは、いきなり実 物が存在。

8/33

実物(オブジェクト)の生成

概念とか設計図の世界 実物(オブジェクト)の世界 contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

Test.st_cont=10;

• static cont();

• Test. cont();

• cont();

実物は、値を蓄えたり、

メソッドを実行したりできる。

(5)

9/33

実物(オブジェクト)の生成

概念とか設計図の世界 実物(オブジェクト)の世界 contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

Test.st_cont=10;

• static cont();

• Test. cont();

• cont();

設計図には、『contentsという整数を保 存する場所がある』と書いてあるので、

実物には、それがある。

10/33

実物(オブジェクト)の生成

概念とか設計図の世界 実物(オブジェクト)の世界 contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

Test.st_cont=10;

• static cont();

• Test. cont();

• cont();

設計図にstaticと書いてあるモノ に関しては、こちらを使用する。

(6)

11/33

実物(オブジェクト)の生成

概念とか設計図の世界 実物(オブジェクト)の世界 contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

Test.st_cont=10;

• static cont();

• Test. cont();

• cont();

contents = 20;

• pushContents();

Data2

st_cont;

• cont();

同じ設計図に基づいて、

2つめのオブジェクトを生成。

12/33

static で無い変数

概念とか設計図の世界 実物(オブジェクト)の世界 contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

Test.st_cont=10;

• static cont();

• Test. cont();

• cont();

contents = 20;

• pushContents();

Data2

st_cont;

• cont();

それぞれのオブジェクトが、値を保 存する場所を独自に持っている。

(7)

13/33

static な変数

概念とか設計図の世界 実物(オブジェクト)の世界

contents = 20;

• pushContents();

Data2

contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

st_cont;

Test.st_cont=10;

• static cont();

• Test.cont();

• cont();

• cont();

staticと書いてあるの で、同じものを利用。

それぞれのオブジェクトは、

独自に値を持たない!

14/33

static な変数に代入 その 1

概念とか設計図の世界 実物(オブジェクト)の世界

contents = 20;

• pushContents();

Data2

contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

st_cont;

Test.st_cont=15;

• static cont();

• Test.cont();

• cont();

• cont();

Test.st_cont=15とすれば、

Data1.st_cont 15に。

(8)

15/33

static な変数に代入 その 2

概念とか設計図の世界 実物(オブジェクト)の世界

contents = 20;

• pushContents();

Data2

contents = 10;

• pushContents();

Data1 Test

int contents;

• pushContents();

static int st_cont; st_cont;

st_cont;

Test.st_cont=20;

• static cont();

• Test.cont();

• cont();

• cont();

ここに値を代入!

Data1.st_count=20

ここに代入と同じ結果に!

当然、 Data2.st_count 20になる!

16/33

前回の課題の解答

(9)

17/33

前回の課題

その1:

次のプログラムを実行しなさい。

レポートとして、

実行結果を報告しなさい。

static がついている変数に注目し、その

結果になった理由を説明しなさい。

class Test{

static int st_data;

int data;

public void test_func01(){

System.out.println(data);

}

public static void test_func02(){

System.out.println(st_data);

} }

class Test{

static int st_data;

int data;

public void test_func01(){

System.out.println(data);

}

public static void test_func02(){

System.out.println(st_data);

} }

サンプルプログラム内のクラス

data;

• test_func01();

設計図

st_data;

• test_func02();

(10)

public class Sample04a{

public static void main(String[] args){

Test dt01 = new Test();

Test dt02 = new Test();

public class Sample04a{

public static void main(String[] args){

Test dt01 = new Test();

Test dt02 = new Test();

サンプルプログラム main 内

data=0;

• test_func01();

dt01

st_data;

• test_func02();

data=0;

• test_func01();

dt02

st_data;

• test_func02();

Test st_data=0;

• test_func02();

[1/6]

dt01.data=100;

dt02.data=200;

System.out.println(dt01.data);

System.out.println(dt02.data);

dt01.data=100;

dt02.data=200;

System.out.println(dt01.data);

System.out.println(dt02.data);

サンプルプログラム main 内

data=100;

• test_func01();

dt01

st_data;

• test_func02();

data=200;

• test_func01();

dt02

st_data;

• test_func02();

Test st_data=0;

• test_func02();

それぞれのインスタン スメンバに代入。

コンソールに

と表示される。

100 200

[2/6]

(11)

System.out.println();

Test.st_data=300;

System.out.println(Test.st_data);

System.out.println(dt01.st_data);

System.out.println(dt02.st_data);

System.out.println();

Test.st_data=300;

System.out.println(Test.st_data);

System.out.println(dt01.st_data);

System.out.println(dt02.st_data);

サンプルプログラム main 内

data=100;

• test_func01();

dt01

st_data;

• test_func02();

data=200;

• test_func01();

dt02

st_data;

• test_func02();

Test

st_data=300;

• test_func02();

クラスメンバに300 代入される。

コンソールに

と表示される。

300 300 300

[3/6]

System.out.println();

dt02.st_data=400;

System.out.println(Test.st_data);

System.out.println(dt01.st_data);

System.out.println(dt02.st_data);

System.out.println();

dt02.st_data=400;

System.out.println(Test.st_data);

System.out.println(dt01.st_data);

System.out.println(dt02.st_data);

サンプルプログラム main 内

data=100;

• test_func01();

dt01

st_data;

• test_func02();

data=200;

• test_func01();

dt02

st_data;

• test_func02();

Test

st_data=400;

• test_func02();

クラスメンバに400 代入される。

コンソールに

と表示される。

400 400 400

[4/6]

ここに代入しよ うとすると...

実際には、

ここに代入!

(12)

System.out.println();

dt01.test_func01();

dt02.test_func01();

System.out.println();

dt01.test_func01();

dt02.test_func01();

サンプルプログラム main 内

data=100;

test_func01();

dt01

st_data;

• test_func02();

data=200;

test_func01();

dt02

st_data;

• test_func02();

Test

st_data=400;

• test_func02();

それぞれのインスタン スは、自分の持って いる値を出力。

コンソールに

と表示される。

100 200

[5/6]

dt01.test_func02();

dt02.test_func02();

Test.test_func02();

} }

dt01.test_func02();

dt02.test_func02();

Test.test_func02();

} }

サンプルプログラム main 内

data=100;

• test_func01();

dt01

st_data;

test_func02();

data=200;

• test_func01();

dt02

st_data;

test_func02();

Test

st_data=400;

test_func02();

クラスオブジェクトが 実行される。

結局、みんな同じ事。

コンソールに

と表示される。

400 400 400

[6/6]

(13)

25/33

前回の課題

その2:

実行結果を報告しなさい。

それぞれのインスタンスが持つ変数

value 注目

し、その結果になった理由を説明しなさい。

Sample04c.java をコンパイル、実行しなさい。

レポートとして、

26/33

回答

class Test{

int value;

Test(){

value=10;

}

Test(int value01){

value=value01*10;

} }

public class Sample04c{

public static void main(String[] args){

Test dt01 = new Test();

Test dt02 = new Test(100);

System.out.println(dt01.value);

System.out.println(dt02.value);

} }

2つ以上のコンストラクタが有る場合、

どちらが実行されるかは、引数で判断される。

引数が無いので、

こちらが実行される。

引数として 整数が一つ 渡されるので、

こちらが実行される。

コンソールに

と表示される。

10 1000

(14)

27/33

前回の課題

その3:

Sample04d.java に、『double型の引数と整数型

の引数を貰い、その除算の結果を出力するメソッド

calc』

を書き加えなさい。

また、calc(10.5, 20.5)の次の行に

calc(10.5, 3) を加えて、実行しなさい。

28/33

もともとのプログラム:

public class Sample04d{

public static void main(String[] args){

calc(10,20);

calc(10.5,20.5);

}

public static void calc(int data01, int data02){

System.out.println(data01*data02);

}

public static void calc(double data01, double data02){

System.out.println(data01+data02);

} }

引数が(整数,整数)

なので、こちらが実行

引数が(double,double なので、こちらが実行 同じクラスのメソッドは、

メソッド名だけで実行できます

(15)

29/33

解答例:

public class Sample04d{

public static void main(String[] args){

calc(10,20);

calc(10.5,20.5);

calc(10.5,3);

calc(10.5,3);

calc(10.5,3);

calc(10.5,3);

}

public static void calc(int data01, int data02){

System.out.println(data01*data02);

}

public static void calc(double data01, double data02){

System.out.println(data01+data02);

}

public static void calc(double data01, public static void calc(double data01, public static void calc(double data01,

public static void calc(double data01, int int int int data02){data02){data02){data02){

System.out.

System.out.

System.out.

System.out.printlnprintlnprintln(data01/data02);println(data01/data02);(data01/data02);(data01/data02);

} }}}}

コンソールに と表示される。

3.5

引数を double int

30/33

継承

(16)

31/33

継承とは

あるクラスが存在しているとき、それを流用して、違うク ラスを記述することができる!。

int data01;

• test_func01();

Test01 int data01;

• test_func01();

Test02

int data02;

もとのクラスをスーパークラス、新しくできたクラスをサ ブクラスと呼びます。

新しくできたサブクラスは、普通のクラスと同様の方法 でインスタンスを生成し、使えます。

32/33

サブクラスの書き方

Test02

int data02;

int data01;

• test_func01();

Test01

class サブクラス名 extends スーパークラス名 { 拡張したい内容を書く。

}

class サブクラス名 extends スーパークラス名 { 拡張したい内容を書く。

}

もとのクラスを拡張(

extends

)する形で書きます。

直感的には、以下のような感じ。

拡張された 部分

スーパー クラス サブ

クラス

(17)

33/33

サブクラスの書き方例

Test02

int data02;

int data01;

• test_func01();

Test01

class Test01{

int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

class Test02 extends Test01{

class Test02 extends Test01{

class Test02 extends Test01{

int int int

int data02;data02;data02;data02;

}}}}

class Test01{

int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

class Test02 extends Test01{

class Test02 extends Test01{

class Test02 extends Test01{

int int int

int data02;data02;data02;data02;

}}}}

スーパークラス

拡張された内容

サブクラス

34/33

class Test01{

int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

}

public class Sample04d{

public static void main(String[] args){

Test02 Test02Test02

Test02 dtdtdt02 = new Test02();dt02 = new Test02();02 = new Test02();02 = new Test02();

以下略 class Test01{

int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

}

public class Sample04d{

public static void main(String[] args){

Test02 Test02 Test02

Test02 dtdtdtdt02 = new Test02();02 = new Test02();02 = new Test02();02 = new Test02();

以下略

生成されたインスタンス

dt02

data02;

data01;

• test_func01();

普通に生成

dt02.data01のように、

普通にアクセス

dt02.test_func01()のように、

普通にアクセス

(18)

35/33

復習:修飾子

class Test03{

private private private

private int data01;

public public public

public int data02;

func(){中略}

}

class Test03{

private private private

private int data01;

public public public

public int data02;

func(){中略}

}

data01;

dt01

data02;

Test03に基づいて 作られたオブジェクト

• func;

dt02 省略

省略

アクセス できない

アクセス できる data01にも

data02にも アクセスできる

その変数が、

どこからアクセスできるか、

範囲を指定

36/33

class Test01{

public public public

public int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

void test_func02(){

data01=10;

} }

class Test01{

public publicpublic

public int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

void test_func02(){

data01=10;

} }

スーパークラスの修飾子の影響 その 1 public 編

dt01(生成されたインスタンス)

data02;

data01;

• test_func01();

Test01

• test_func02();

dt01.test_func01は、

色々なところからアクセスできる dt02 省略

省略

(19)

37/33

class Test01{

private private private

private int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

void test_func02(){

data01=10;

} }

class Test01{

private privateprivate

private int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

void test_func02(){

data01=10;

} }

スーパークラスの修飾子の影響 その 2 private 編

dt01(生成されたインスタンス)

data02;

data01;

• test_func01();

Test01

• test_func02();

dt01.test_func02は、

data01にアクセスできないできないできないできない dt01.test_func01は、

data01 アクセスできる

dt02 省略

省略

38/33

修飾子 protected

サブクラスにはアクセスを許すが他のクラスにはアクセ スを許さないことを示すアクセス修飾子。

protected

がついたメンバは、

サブクラス内からは

public

メンバのように

別パッケージのクラスから見ると

private

メンバのよう に

みることができる。

(20)

39/33

class Test01{

protected protected protected

protected int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

void test_func02(){

data01=10;

} }

class Test01{

protected protectedprotected

protected int data01;

void test_func01(){中略}

}

class Test02 extends Test01{

int data02;

void test_func02(){

data01=10;

} }

修飾子 protected

dt01(生成されたインスタンス)

data02;

data01;

• test_func01();

Test01

• test_func02();

dt01.test_func02は、

data01にアクセスできるできるできるできる dt01.test_func01は、

data01 アクセスできる

dt02 省略

省略

40/33

class Test01{

int data01;

void void void

void test_functest_functest_functest_func01(){01(){01(){01(){中略中略中略中略}}}}

}

class Test02 extends Test01{

int data02;

void void void

void test_functest_functest_functest_func01(){01(){01(){01(){中略中略中略中略}}}}

}

class Test01{

int data01;

void void void

void test_functest_functest_func01(){test_func01(){01(){中略01(){中略中略}}}}中略 }

class Test02 extends Test01{

int data02;

void void void

void test_functest_functest_func01(){test_func01(){01(){中略01(){中略中略}}}}中略 }

メソッドのオーバーライド

dt01(生成されたインスタンス)

data02;

data01;

• test_func01();

Test01

test_func01();

サブクラスの方で、

スーパークラスと同じ名前・引数の メソッドを定義した場合、

サブクラスで書いた方が有効に メソッドのオーバーライド

dt01.test_func01()として、

こちらが使われる。

こちらは使われない

(21)

41/33

class Test01{

int data01;

void void void

void test_functest_functest_functest_func01010101()()(){{{{中略() 中略中略中略}}}}

}

class Test02 extends Test01{

int data02;

void void void

void test_functest_functest_functest_func01010101((((intintintint j)j)j)j){{{{中略中略中略中略}}}}

}

class Test01{

int data01;

void void void

void test_functest_functest_func01test_func0101()01()()(){{{{中略中略中略}}}}中略 }

class Test02 extends Test01{

int data02;

void void void

void test_functest_functest_func01test_func0101((((int01 intint j)int j)j){{{{中略j) 中略中略}}}}中略 }

メソッドのオーバーロード

dt01(生成されたインスタンス)

data02;

data01;

test_func01();

Test01

test_func01(int);

サブクラスの方で、

スーパークラスと同じ名前、

異なる引数の

メソッドを定義することで、

メソッドのオーバーロードが可能

どちらが使われるかは、

引数で判断される

42/33

コンストラクタ

サブクラスのコンストラクタで初期化されなかった、スー パークラスから継承した変数は、スーパークラスの引 数無しのコンストラクタで初期化される。

スーパークラスの引数がある場合のコンストラクタを呼 び出したいときは、明示的に呼び出す必要がある。

呼び出し方は、

とする。これは、サブクラスのコンストラクタの

1

行目に 書く必要がある。

super(

引数

)

super(

引数

)

(22)

43/33

例 その 1 : 引数無し

class Test01{

int value01a;

Test01(){

value01a=10;

}

Test01(int a){

value01a=a*100;

} }

class Test02 extends Test01{

int value02a;

Test02(){

value02a=20;

}

Test02(int a, int b){

super(a);

value02a=b*1000;

} }

public class Sample05a{

public static void main(String[] args){

Test02 dt01 = new Test02();

System.out.println(dt01.value01a);

System.out.println(dt01.value02a);

} }

これを、

実行 これも、

実行

value02aしか 初期化してない

44/33

例 その 2 : 引数有り

class Test01{

int value01a;

Test01(){

value01a=10;

}

Test01(int a){

value01a=a*100;

} }

class Test02 extends Test01{

int value02a;

Test02(){

value02a=20;

}

Test02(int a, int b){

super(a);

value02a=b*1000;

} }

public class Sample05b{

public static void main(String[] args){

Test02 dt01 = new Test02(10);

System.out.println(dt01.value01a);

System.out.println(dt01.value02a);

} }

super(a)は、

これを実行

これを、

実行 1行目に 書く

(23)

45/33

例 その 3 : super なし

class Test01{

int value01a;

Test01(){

value01a=10;

}

Test01(int a){

value01a=a*100;

} }

class Test02 extends Test01{

int value02a;

Test02(){

value02a=20;

}

Test02(int a, int b){

value02a=b*1000;

} }

public class Sample05c{

public static void main(String[] args){

Test02 dt01 = new Test02(10);

System.out.println(dt01.value01a);

System.out.println(dt01.value02a);

} }

これを、

実行。

これも、

実行

value02aしか 初期化してない

参照

関連したドキュメント

教育用に用いられてきた。現在では本来の Basic を 現在の PC のために拡張した言語のほか, Microsoft 社からは VisualBasic や最近では

Erlang eXchange ☆ 15 というイベントがロンドンで開 催され,3

目的プログラム 人間が読み書きするのは困難な2進数の羅列であ

プログラミング言語には、多くの種 類がある。 その背景には、様々な 概念(パラダイム) がある. 背景のパラダイムを理解する

 文脈自由文法では、開始記号か ら始まり生成規則にしたがって 書き換え ( 導出)を繰り返す. 

BNF (Backus Naur form) とは 構文を記述するための表記法 1959 バッカス(John Backus)が考.

public static void main(String[] args) { System.out.println("Hello, world!");. }

static long static float static double static long static float static double