プログラミング

プログラミング初心者のJavaSilver修羅の道#8〜クラスとオブジェクト〜


プログラミング初心者の私が実務未経験転職するにあたり、会社の研修資料以外にも本格的に自主的な勉強をするためについに始めました。今回はそのシリーズの第8段となります。過去記事は下記から見れます。

現在使用している参考書は「オラクル認定資格教科書 JavaプログラマSilver SE11」いわゆる紫本と呼ばれる参考書です。今後は白本・黒本を活用しつつ勉強していくと思います。

オラクル認定資格教科書 JavaプログラマSilver SE11

インスタンス化

クラスを元にメモリ上に実体(オブジェクト)を生成すること。

インスタンス化にはnewキーワードを使用します。

データ型 a = new クラス名 () ;

「呼び出し」は、「どのオブジェクトに対して呼び出しを行いたいのか」を表現するために、「変数名.メソッド名()」となります。

メンバ

クラスの直下に用意された変数やメソッドの総称です。

メンバ変数(フィールド)

そのクラスが持つべき属性を表現する為に使用します。
※メンバ変数には2種類の変数があります。

インスタンス変数:オブジェクトごとに存在する変数

static変数:クラスに対して存在する変数

this

「this」は自分自身を意味するキーワードで、メソッドの中でインスタンス変数x,yの値を参照する時はそれぞれthis.x,this.yと書きます。

class Point {
  int x ; int y ;
  void printPosition ( ) {
    System.out.println("座標値は(" + this.x + "," + this.y + ")です") ;
  }
}

変数のスコープ

メンバ変数

・「クラス内のどこからでも使用可能」。また、デフォルト値で初期化される。

ローカル変数

・宣言したブロック内(if文,for文内…)でしか使用できない。また、明示的な初期化が必要。

コンストラクタ

インスタンス化される時に最初に呼び出されるブロックを定義するものです。主な特徴としては以下のものが挙げられます。

①名前がクラス名と同じ

②戻り値は持たない(戻り値の型宣言もしない)

③必要に応じて引数を受け取ることができる

【定義側】

class Employee {
  int id ;
  //コンストラクタの定義
  Employee (int i) {
    id = i ;
  }
}

【呼び出し側】

Employee e = new Employee(100);//コンストラクタの呼び出し

上記ではコンストラクタを使用した時の例を紹介しましたが、コンストラクタを使用しなかった場合はどうなるのでしょうか。次の例を見てください。

呼び出し側では、同じ処理を2行も記述する必要が出てくるのがわかると思います。

デフォルトコンストラクタ

ここで1つ気になることがあります。コンストラクタを定義していないにも関わらず、newしているのはどういうことなのでしょうか?

実は「コンストラクタを明示的に定義しなかった場合、コンパイラによってコンストラクタが自動で追加」されます。このコンストラクタのことを「デフォルトコンストラクタ」と呼びます。

デフォルトコンストラクタの定義

①引数はもたない

②実装は空(スコープ内には何も記述されていない)

③クラスに1つもコンストラクタを定義していない場合のみ追加される

オーバーロード

1つのクラス内同じ名前のメソッドやコンストラクタを複数定義出来ます。
しかし、それぞれのメソッドを区別するための下記条件が存在します。

引数の並び

データ型

引数の数が異なる

変数名戻り値の型が異なっていても上記が一致していればコンパイルエラーとなってしまいます。

ちなみに、オーバーロードされたメソッドの呼び出される優先順位は次の順番になります。

「完全一致>暗黙の型変換>Boxing>可変長引数」

明確に定義したメソッドが優先して呼び出されます。

(例)
参照変数名.method(10,20);と呼び出した場合
void method(int… a) {}
void method(int a, int b) {} //先に呼び出される

static

static変数はクラス変数、staticメソッドはクラスメソッドと呼ばれています。

staticメンバとインスタンスメンバの違い〜

staticメンバを持つクラスをもとに複数オブジェクトがインスタンス化されても1箇所に用意されるため、staticメンバは各オブジェクトから共有して使用されます。

クラス全体で扱うデータを格納するために使用します。 

では、異なるクラス間でのアクセス方法はどうなるのでしょうか?

具体的な例を見ていきましょう。

<Testクラス>

<Mainクラス>

「staticメンバ」から「インスタンスメンバ」へのアクセスは×

→インスタンス化した後に、参照変数名を使用することで呼び出しが可能。
(インスタンスメンバの呼び出しはどのオブジェクトに対して行うのか、明示する必要がある。)

Test obj = new Test ( );
return obj.instanceVal;

※インスタンスメンバは、必ずインスタンス化しないと呼び出すことは出来ません。

練習問題

ではここで練習問題をいくつか紹介します。

<問題①>以下の画像の実行結果はどうなりますか?

<問題②>以下の画像でコンパイルエラーとなる行はどこですか?

<解答①> 10

12行目のnumには40が格納されていますが、そのnum変数を呼び出し元に返していないため10行目で宣言した変数の値の10が出力されます。

※但し、配列の場合は「参照型」のため、同じ配列を参照することになり、40が出力されます。

<解答②> 7、8、17行目がコンパイルエラー

7・8行目は、staticメンバからインスタンスメンバへのアクセスを行なっているためコンパイルエラーとなります。
17行目は、インスタンスメンバにおいてクラス名.メソッド名」での呼び出しは許可されていないためコンパイルエラーとなります。

では、また👋

ABOUT ME
ヒロ
社会人4年目/25歳/食品商社で2年間営業した後、IT業界にシステムエンジニアとして転職/Java,PHP言語を扱う開発エンジニア