今日は、テスト返しの残り時間で、4年の情報構造論で、リスト構造などの内容を進める前に、3年プログラミング応用でクラスなどに自信がない人向けの簡単レクチャ。
クラスは、データ構造と手続き
例えば、名前と年齢のデータをクラスで扱うのであれば、以下のようなコードが基本となるだろう。
import java.util.*; class NameAge { String name ; // インスタンス変数 int age ; // インスタンス変数 static int count = 0 ; // クラス変数 // コンストラクタ NameAge( String s , int a ) { this.name = s ; this.age = a ; count++ ; } // メソッド void print() { System.out.println( this.name + "," + this.age ) ; System.out.println( "member = " + count ) ; } } ; public class Main { public static void main(String[] args) throws Exception { NameAge tsaitoh = new NameAge( "tsaitoh" , 59 ) ; tsaitoh.print() ; System.out.println( "age = " + tsaitoh.age ) ; NameAge tomoko = new NameAge( "tomoko" , 48 ) ; tomoko.print() ; } } 実行結果 tsaitoh,59 member = 1 age = 59 tomoko,48 member = 2
クラスとは、データ構造(オブジェクト)とそのデータ構造を扱うための関数(メソッド)をまとめて扱う。
クラス NameAge の中で宣言されている、NameAge() の関数は、オブジェクトを初期化するための関数(メソッド)であり、特にコンストラクタと呼ばれる。
実際にデータを保存するための tsaitoh や tomoko とよばれる変数に NameAge オブジェクトの実体を作る時には 「new クラス名」 とやることで、初期化ができる。
イメージでは、下図のようなデータ構造ができあがる。
でも、年齢の覚え方は、将来的に誕生日を覚えるように変化するかもしれない。この際に、Main 関数の中で age を使うと後で混乱の元になるかもしれない。こういう時は、NameAge クラス以外では中身を勝手に使わせないために、インスタンス変数などに public / private といったアクセス制限を加える。
import java.util.*; class NameAge { private String name ; // インスタンス変数 private int age ; // インスタンス変数 public static int count = 0 ; // クラス変数 // コンストラクタ public NameAge( String s , int a ) { this.name = s ; this.age = a ; count++ ; } // メソッド public void print() { System.out.println( this.name + "," + this.age ) ; System.out.println( "member = " + count ) ; } } ; public class Main { public static void main(String[] args) throws Exception { NameAge tsaitoh = new NameAge( "tsaitoh" , 59 ) ; tsaitoh.print() ; System.out.println( "age = " + tsaitoh.age ) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ここがエラーになる。NameAge::age は private NameAge tomoko = new NameAge( "tomoko" , 48 ) ; tomoko.print() ; } }
クラス自体も、public class NameAge … のように宣言することもあるが、public なクラスは 1つ の *.java ファイルの中に1つしか書けないというルールがあるので要注意。
中間試験問題の回答
import java.util.*; import java.util.* ; class Item { int id ; String name ; int price ; Item( int i , String n , int p ) { this.id = i ; this.name = n ; this.price = p ; } } ; class Buy { int id ; int count ; Buy( int i , int n ) { this.id = i ; this.count = n ; } } ; public class Main { static Item[] item_list = { new Item( 1010 , "orange" , 50 ) , new Item( 1020 , "apple" , 100 ) , new Item( 1022 , "pineapple" , 1000 ) , } ; static Buy[] buy_list = { new Buy( 1010 , 5 ) , new Buy( 1020 , 3 ) , new Buy( 1022 , 1 ) , } ; public static void main( String[] args ) { System.out.println( total_price( item_list , buy_list ) ) ; } static int total_price( Item[] i_list , Buy[] b_list ) { int sum = 0 ; for( Item item : i_list ) for( Buy buy : b_list ) if ( item.id == buy.id ) sum += item.price * buy.count ; return sum ; } // static int total_price( Item[] i_list , Buy[] b_list ) { // int sum = 0 ; // for( int i = 0 ; i < i_list.length ; i++ ) // for( int j = 0 ; j < b_list.length ; j++ ) // if ( i_list[ i ].id == b_list[ j ].id ) // sum += i_list[ i ].price * b_list[ j ].count ; // return sum ; // } }
練習問題
科目(Subject)と学生(Student)の情報があり、科目を受講した成績(Result)で成績を管理している。
このデータを管理するためのクラスを宣言し、下に示すような出力が得られるプログラムを作成せよ。
今回の中間テストで成績が悪かった人は、テスト前に示したレポート課題ではなく下記の課題で提出してよいこととする。
科目: Subject id name teacher // Subject[] subject_table = { 10010 情報構造論 t-saitoh // new Subject( 10010 , "情報構造論" , "t-saitoh" ) , 10020 電気磁気学 takaku // new Subject( .... 10030 電気回路 komatsu // } ; 成績: Result s_id id point // Result[] result_table = { 16213 10020 83 // new Result( 16213 , 10020 , 83 ) , 18348 10010 95 // new Result( ... 17101 10030 64 // } ; 16213 10010 89 学生: Student s_id name age // Student[] student_table = { 16213 斉藤太郎 18 // new Student( 16213 , "斉藤太郎" , 18 ) , 17101 山田次郎 19 // new Student( ... 18348 渡辺花子 18 // } ; 以下のようなデータが出力されること 斉藤太郎 電気磁気学 83 渡辺花子 情報構造論 95 山田次郎 電気回路 64 斉藤太郎 情報構造論 89