第2章 クラスの基本

2.3 メンバへのアクセス方法について

クラスを利用しオブジェクトを生成する方法について前節で学習してきました。しかしオブジェクトを生成しただけでは本当にクラスを最大限利用したことにはなりません。オブジェクトに定義されている「メンバ(フィールド変数やメソッド)」を利用してこそ本来の意味があります。では実際にメンバへのアクセス方法について学習していきましょう。

2.3.1 メンバへのアクセス方法

生成されたオブジェクトのメンバにアクセスする場合には「.」(ドット)を使ってアクセスします。
まずはその基本構文を見てみましょう。

凡例:フィールド変数とメソッドへのアクセス方法

2.2.1項で定義した「Computer」クラスを例にしています。
下記のように「Computer」オブジェクトを1つ生成すると、コンピュータ1台のメモリの設定や音を鳴らすといった、そのオブジェクトのフィールド変数やメソッドへのアクセスができるようになります。
生成したオブジェクトは「os、cpu、memory」という値を格納できるフィールド変数(属性)と、「起動、終了、音を鳴らす」などが行えるメソッド(操作)を持ちます。値を設定したい場合は、このフィールド変数(属性)へ実際に値を代入し、何か動作をさせたければメソッド(操作)を利用すれば良いのです。

  Computer com = new Computer();  //オブジェクト生成
  com.os = "WindowsXP";	          //フィールド変数「os」へアクセス
  com.start();                    //メソッド「start」へアクセス
  

「com.os」と記述すれば、comがさす「コンピュータ」オブジェクトのOSを表すことができ、OSをWindowsXPにしたい場合は上記のように代入し、「com.start();」と記述すれば起動という操作が行えることになります。
それでは、次の項にて実際にメンバへアクセスするサンプルを紹介します。

2.3.2 フィールド変数に値を設定するプログラム

オブジェクトのフィールド変数へ値をダイレクトに設定し、その結果を画面に出力します。
フィールド変数へのアクセス方法について学習しましょう。

① ソース・フォルダー: myproj_basic/src
② パッケージ: jp.co.f1.basic.ch02
③ 名前: FieldVariable
④ 作成するメソッド・スタブの選択: public static void main(String[] args) にチェックを入れる


  package jp.co.f1.basic.ch02;

  class Computer2 {
    String os;
    int memory;
  }

  public class FieldVariable {
    public static void main(String[] args) {
      Computer2 com = new Computer2();

      com.os = "WindowsXP";
      com.memory = 2048;

      System.out.println("パソコンのOSは「" + com.os + "」です。");
      System.out.println("メモリサイズは「" + com.memory + "MByte」です。");
    }
  }
  
実行結果

解説
3~6行目でフィールド変数のみを持つクラス「Computer2」が定義されています。
10行目でComputer2型のオブジェクト変数comに、new演算子を利用してオジェクトを生成し代入しています。

12行目でcomオブジェクトのフィールド変数「os」にアクセスし文字列「WindowsXP」を格納します。 13行目もcomオブジェクトのフィールド変数「memory」にアクセスし数値「2048」を格納します。

  com.os = "WindowsXP";
  com.memory = 2048;
  

12、13行の処理をイメージで表現すると、以下の図2.3.1のようになります。

図 2.3.1: フィールド変数へ値の格納

15、16行目でcomオブジェクトのフィールド変数「os」と「memory」にアクセスし、各値を表示しています。

  System.out.println("パソコンのOSは「" + com.os + "」です。");
  System.out.println("メモリサイズは「" + com.memory + "MByte」です。");
  

15、16行目の処理をイメージで表現すると、以下の図2.3.2のようになります。

図 2.3.2: フィールド変数値の参照

今回のサンプルではフィールド変数にアクセスする仕組みについて学習しました。1章の「クラスとオブジェクトの関係」でも案内していますが、1つのクラスからオブジェクトはいくつでも生成することができます。次の項では複数のオブジェクトを生成するサンプルを紹介します。

2.3.3 複数のオブジェクトを作成するプログラム

同じクラスから生成された2つのオブジェクトの各々のフィールド変数に値を設定し、その結果を表示します。同じクラスから生成された複数のオブジェクトが、独立した個々のオブジェクトとなり、オブジェクト毎にフィールド変数の値を保持できることを学習しましょう。

① ソース・フォルダー: myproj_basic/src
② パッケージ: jp.co.f1.basic.ch02
③ 名前: ManyObjects
④ 作成するメソッド・スタブの選択: public static void main(String[] args) にチェックを入れる

  package jp.co.f1.basic.ch02;

  class Computer3 {
    String os;
    int memory;
  }

  public class ManyObjects {
    public static void main(String[] args) {
      // 同じComputer3クラスからオブジェクトを2つ生成する
      Computer3 com1 = new Computer3();
      Computer3 com2 = new Computer3();

      // 個々のオブジェクトのフィールド変数に、各データを格納する
      com1.os = "WindowsXP";
      com1.memory = 2048;
      com2.os = "Windows2000";
      com2.memory = 512;

      // 個々のオブジェクトのフィールド変数の値を参照し、結果を画面に表示する
      System.out.println("パソコン1のOSは「" + com1.os + "」です。");
      System.out.println("メモリサイズは「" + com1.memory + "MByte」です。");
      System.out.println("パソコン2のOSは「" + com2.os + "」です。");
      System.out.println("メモリサイズは「" + com2.memory + "MByte」です。");
    }
  }
  
実行結果

解説

3~6行目でフィールド変数のみのメンバを持つクラス「Computer3」が定義されています。

  class Computer3 {
    String os;
    int memory;
  }
  

11、12行目でComputer3型のオブジェクト変数com1とcom2に、オジェクトをnew演算子で生成し代入しています。型は同じ「Computer3」ですが、オブジェクトcom1とcom2は個々として独立します。

  Computer3 com1 = new Computer3();
  Computer3 com2 = new Computer3();
  

11、12行目の処理をイメージで表現すると、以下の図2.3.3のようになります。

図 2.3.3: 複数オブジェクトを作成

15、16行目でcom1オブジェクトのフィールド変数にアクセスし各値を格納します。
17、18行目でcom2オブジェクトのフィールド変数にアクセスし各値を格納します。

  com1.os = "WindowsXP";
  com1.memory = 2048;
  com2.os = "Windows2000";
  com2.memory = 512;
  

15~18行目の処理をイメージで表現すると、以下の図2.3.4のようになります。

図 2.3.4: 複数オブジェクトのフィールドへ値の格納

21、22行目でcom1オブジェクトのフィールド変数「os、memory」にアクセスし、各値を表示しています。
23、24行目でcom2オブジェクトのフィールド変数「os、memory」にアクセスし、各値を表示しています。

  System.out.println("パソコン1のOSは「" + com1.os + "」です。");
  System.out.println("メモリサイズは「" + com1.memory + "MByte」です。");
  System.out.println("パソコン2のOSは「" + com2.os + "」です。");
  System.out.println("メモリサイズは「" + com2.memory + "MByte」です。");
  

21~24行目の処理をイメージで表現すると、以下の図2.3.5のようになります。

図 2.3.5: 複数オブジェクトのフィールド変数値の参照

今回のサンプルでは、生成されたオブジェクトの独立性について学習しました。
次はフィールド変数へアクセスするだけではなく、メソッドへアクセスするサンプルを紹介していきます。

2.3.4 メソッドについて

クラスには様々な目的に合わせ複数のメソッドを定義することができます。これまでの学習では、mainメソッドが存在するクラスにmainメソッド以外の自作メソッドを定義し、オブジェクトの生成を行わずに使用していました。その際には、下記のように記述を行っていました。

今後は、オブジェクトを生成し呼び出すメソッドについても扱っていくことになります。オブジェクトを生成し、呼び出すメソッドを定義する場合は以下のように定義します。

オブジェクトを使って呼び出すメソッドの場合、staticというキーワードをつけません。
「static」が付いたメソッドのことを「クラスメソッド」、付かないメソッドを「インスタンスメソッド」と呼びます。なお、基本構文の初めについている「public」は「アクセス修飾子」と呼ばれ、他のクラスから利用される場合のアクセスを制限するためのキーワードの1種です。どこからでもアクセスが可能という意味を持っており、アクセスを制限しない場合には、「public」を付けるのが一般的です。
「static」キーワードについては6章で、「public」のアクセス修飾子については3章で詳しく説明しますので、今は書式の通り覚えておいて下さい。

メソッドパターン

戻り値の型や引数の数や組み合わせでメソッドの定義は難しく感じるかもしれませんが、基本はこの4つに分類されます。まずはこのパターンを覚えておいて処理に必要なメソッドを定義できるようにしましょう。
メソッドについて簡単にですが復習できたと思いますので、クラスに定義されたメソッドにアクセスするプログラムを次項で紹介します。

2.3.5 インスタンスメソッドを呼び出すプログラム

インスタンスメソッドを呼び出して、フィールド変数の変更前と変更後の値を画面に表示させます。メソッドは引数なし、戻り値なしのパターンを定義しています。インスタンスメソッドの呼び出し方について学習しましょう。

① ソース・フォルダー: myproj_basic/src
② パッケージ: jp.co.f1.basic.ch02
③ 名前: InstanceMethod1
④ 作成するメソッド・スタブの選択: public static void main(String[] args) にチェックを入れる

  package jp.co.f1.basic.ch02;

  class Computer4 {
    String os;
    int memory;

    // フィールド変数の値を表示するメソッド
    public void show() {
      System.out.println("パソコンのOSは「" + os + "」です。");
      System.out.println("メモリサイズは「" + memory + "MByte」です。");
    }
  }

  public class InstanceMethod1 {
    public static void main(String[] args) {
      // Computer4クラスからオブジェクトを生成する
      Computer4 com = new Computer4();

      // データ格納前にメソッド呼び出し(1回目)
      System.out.println("■1回目のメソッド呼び出し");
      com.show();

      // オブジェクトのフィールド変数に、各データを格納する
      com.os = "WindowsXP";
      com.memory = 2048;

      // データ格納後にメソッド呼び出し(2回目)
      System.out.println("\n■2回目のメソッド呼び出し");
      com.show();

    }
  }
  
実行結果

解説
3~12行目でフィールド変数とメソッドを持つクラス「Computer4」が定義されています

    class Computer4 {
      String os;
      int memory;

      //フィールド変数の値を表示するメソッド
      void show(){
        System.out.println("パソコンのOSは「" + os + "」です。");
        System.out.println("メモリサイズは「" + memory + "MByte」です。");
      }
    }
    

17行目でComputer4型のオブジェクト変数comにオジェクトをnew演算子で生成し代入しています。

    Computer4 com = new Computer4();
    

17行目の処理をイメージで表現すると、以下の図2.3.6のようになります。

図 2.3.6: メソッドありオブジェクトの生成

これまでのComputerクラスとは違いメソッドも定義されています。オブジェクトを生成することでメソッドにアクセスし利用が可能になります

21行目でフィールド変数にデータを格納する前に、1回目のshow()メソッド呼び出しを行っています。

    com.show();
    

21行目の処理をイメージで表現すると、以下の図2.3.7のようになります。

①「com.show();」と記述し、変数comに格納されているオブジェクトの場所情報からshowメソッドにアクセスします。アクセス後は処理がshow()メソッド内に移ります。
②show()メソッド内部からフィールド変数「os、memory」にアクセスし値を取得します。
③②で取得した値をもとに画面に結果を出力します。
④showメソッド内の表示処理が終るとmainメソッド内に処理が戻ります。

図 2.3.7: オブジェクトからメソッドを呼び出す

ここで気になる点が1つあります。それは、オブジェクトのフィールド変数に初期値が設定されている点です。
クラスの定義では以下のようになっていたのを思い出してください。

上記のように特に初期値の設定は行っていません。ではなぜ、フィールド変数の「os、memory」に値が設定されているのでしょうか。その答えはオブジェクト作成時に、フィールドに宣言した変数の型にあう規定値を自動で設定する仕組みが働いているからです。この機能の働きによりString型変数osには「null」を、int型変数memoryには「0」を初期値として設定されていた訳です。規定値の一覧を以下の表2.3-1に示します。

1回目のshow()メソッド呼び出しの後に、24、25行目でcomオブジェクトのフィールド変数に各値を格納しています。

  com.os = "WindowsXP";
  com.memory = 2048;
  

フィールド変数にデータ格納後、29行目で2回目のshow()メソッド呼び出しを行っています。

  com.show();
  

29行目の処理をイメージで表現すると、以下の図2.3.8のようになります。
①comオブジェクトからアクセスして「show()メソッド」呼び出します。アクセス後は処理がshow()メソッド内に遷移します。
②show()メソッド内からフィールド変数「os、memory」にアクセスし値を参照します。
③②で参照して取得した値を画面にを出力します。
④showメソッド内の表示処理が終るとmainメソッド内に処理が戻ります。

図 2.3.8: オブジェクトからメソッドを再度呼び出す

このプログラムのポイントはshowメソッドに「何度もアクセスできる」ことと、行う処理はあくまで「その時点」のフィールド変数の値を参照し、画面に結果を表示するということです。
このようなメソッドを用意しておくことで、オブジェクト内のフィールド変数の値を確認する時に非常に便利になります。

続いて次の項ではメソッドの呼び出しパターンについて、別のプログラムを紹介していきます。

2.3.6 オブジェクトの様々なメソッドを呼び出すプログラム

オブジェクト内に定義されているメソッドから他のメソッドを呼び出します。さらに色々なパターンのメソッドを定義し使用しています。プログラムが長くなり若干複雑な流れをしていますが、迷わないように解説と解説内のポイントをよく読み学習していきましょう。

① ソース・フォルダー: myproj_basic/src
② パッケージ: jp.co.f1.basic.ch02
③ 名前: InstanceMethod2
④ 作成するメソッド・スタブの選択: public static void main(String[] args) にチェックを入れる

  package jp.co.f1.basic.ch02;

  class Computer5 {
    String os;
    int memory;

    // メッセージとパソコン情報を表示するメソッド
    public void showComputer() {
      System.out.println("パソコンの情報を表示します。");
      // クラス内のshowメソッドを呼び出す
      show();
    }

    // フィールド変数の値を表示するメソッド
    public void show() {
      System.out.println("OSは「" + os + "」です。");
      System.out.println("メモリサイズは「" + memory + "MByte」です。");
    }

    // フィールド変数よりOSの値を取得する
    public String getOs() {
      return os;
    }

    // フィールド変数よりMemoryの値を取得する
    public int getMemory() {
      return memory;
    }

    // フィールド変数に値を設定するメソッド
    public void setOsMemory(String name, int size) {
      os = name;
      memory = size;
      System.out.println("OSを「" + name + "」に、メモリサイズを「" + size
          + "MByte」に変更しました。");
    }
  }

  public class InstanceMethod2 {
    public static void main(String[] args) {
      // Computer5クラスからオブジェクトを生成する
      Computer5 com = new Computer5();

      // オブジェクトのフィールド変数に、各データを格納する
      com.os = "WindowsXP";
      com.memory = 2048;

      // メソッドを利用してフィールド変数に格納しているデータを取得
      System.out.println("パソコンのOSは「" + com.getOs() + "」です。");
      System.out.println("メモリサイズは「" + com.getMemory() + "MByte」です。");

      // オブジェクトのフィールド変数に、各データを再格納する
      com.setOsMemory("Windows2000", 512);

      // showComputerメソッド呼び出し
      com.showComputer();
    }
  }
  
実行結果

解説
3行~37行目にフィールド変数とメソッドを持つクラス「Computer5」が定義されています。

  class Computer5 {
    String os;
    int    memory;
    …
    各種メソッド ※表2.3.2を参照
    …
  }
  

この「Computer5」クラスには以下のメソッドが定義されています。色々なパターンのメソッドを設定している所がポイントになります。

42行目でComputer5型のオブジェクト変数comにオジェクトをnew演算子で生成し代入しています。

  Computer5 com = new Computer5();
  

45、46行目にフィールド変数に各値を格納しています。

  com.os = "WindowsXP";
  com.memory = 2048;
  

49行目で変数comのオブジェクト参照情報から「getOs()メソッド」を呼び出し、フィールド変数osの値取得してを画面にメッセージと共に表示します。

  System.out.println("パソコンのOSは「" + com.getOs() + "」です。");
  

49行目の処理をイメージで表現すると、以下の図2.3.9のようになります。
①comオブジェクトからアクセスして「getOs()メソッド」呼び出します。アクセス後は処理がgetOs()メソッド内に遷移します。
②getOs()メソッド内ではフィールド変数「os」を参照します。
③フィールド変数「os」を参照して取得できた値を、戻り値としてmain()メソッドに返します。
④mainメソッドに処理が戻り、戻り値の結果を画面にメッセージと共に表示します。

図 2.3.9: オブジェクトからgetOs()メソッドを呼び出す

50行も49行と同じように変数comのオブジェクト参照情報から「getMemory()メソッド」を呼び出し、フィールド変数memoryの値を取得して画面にメッセージと共に表示します。

  System.out.println("メモリサイズは「" + com.getMemory() + "MByte」です。");
  

53行目で変数comのオブジェクト参照情報から「setOsMemory()メソッド」に各引数情報を渡して呼び出し、その引数情報をフィールド変数osとmemoryに設定しています。

  com.setOsMemory("Windows2000",512);
  

53行目の処理をイメージで表現すると、以下の図2.3.10のようになります。
①comオブジェクトからアクセスして「setOsMemory()メソッド」呼び出します。アクセス後は処理が
setOsMemory ()メソッドに遷移します。
②setOsMemory()メソッド内では引数で受け取った値をフィールド変数「os、memory」に格納します。
③設定内容の結果を画面に表示します。
④結果表示後にmain()メソッドに処理が戻ります。

図 2.3.10: オブジェクトからsetOsMemory()メソッドを呼び出す

ここでのポイントはmainメソッドから呼び出した「setOsMemoryメソッド」に与えた引数の値がオブジェクト内のフィールド変数に格納される所です。毎回「オブジェクト変数名.フィールド変数名」でアクセスするのではなくフィールド変数に値を設定するメソッドを準備しておけば大変便利になります。
今回のメソッドでは2つの値を引数に与えてフィールド変数に格納するものでしたが、個別に設定するメソッドを用意するのが一般的です。
フィールド変数に値を設定するメソッドと、逆に値を参照して返してくれるメソッドのことをJavaでは「アクセサメソッド」と呼びます。詳しい説明は3章で行いますので、「アクセサメソッド」という言葉を覚えておいて下さい。

56行目で変数comのオブジェクト参照情報から「showComputer()メソッド」に呼び出して情報を表示しています。このshowComputer()メソッド内からさらにshow()メソッドが呼び出されています。

  com.showComputer();
  

56行目の処理をイメージで表現すると、以下の図2.3.11のようになります。
①comオブジェクトからアクセスして「showComputer()メソッド」呼び出します。アクセス後は処理が
showComputer ()メソッドに遷移します。
②showComputerメソッド内で、固定のメッセージを画面に出力します。
③同じオブジェクト内からshow()メソッドを呼び出します。呼び出し後は処理がshow ()メソッドに遷移します。
④showメソッド内で各フィールド変数の値を画面に表示します。
⑤フィールド変数の値を表示後に再度showComputer()メソッドに処理が戻ります。
⑥showComputerに遷移後は処理がもうないため、mainメソッドに処理が戻ります。

図 2.3.11: オブジェクトからshowComputer()メソッドを呼び出す

ここでのポイントは同一のクラス内に定義されている、メソッド同士は自由に呼び合えるところです。但し「static」キーワードが付くと前提が変わってきます。「static」に関する説明は6章で詳しく説明します。

NEXT>> 2.4 参照型について