【第15回】初心者のJavaプログラミング【クラスの作成,コンストラクタ】
こんばんは。
昨日書けなかったので、今日はちゃんと書きます。
今まで何気なく使っていたクラスについて書いていきます。
長くなるかもしれませんが、良かったら見ていって下さい。
クラスの基本
クラスの要素としては、状態を表す変数、動作や機能を表すメソッド、あとコンストラクタといわれるものの3種類があります。
以前に書いた通り、変数には静的変数とインスタンス変数の2種類があります。同じくメソッドも静的メソッドとインスタンスメソッドの2種類があります。
この2つは以前でてきたので聞いたことがあるとは思いますが、コンストラクタは初めてですよね。
コンストラクタとは、メソッドの仲間なのですが、かなり特殊なメソッドで、インスタンスを生成するときに使います。
以下がインスタンス変数、インスタンスメソッド、コンストラクタの書き方です。
class クラス名 { // インスタンス変数 型 変数名; 型 変数名; // コンストラクタ クラス名(引数) { コンストラクタの中身 } // メソッド 戻り値型 メソッド名(引数) { メソッドの中身 } }
インスタンス変数の宣言はそんなに今まで通りです。
コンストラクタですが、コンストラクタはクラス名と同じになります。
具体的な例を一つあげます。
class Car { // インスタンス変数 String carType; String bodyColor; int size; // コンストラクタ Car(){} } class CarTest { public static void main( String args[] ) { // Carクラスの変数にCarクラスから生成したオブジェクトを入れる。 // (carオブジェクトは参照型変数なので、正確にはオブジェクトのアドレスが代入される) // Car()コンストラクタを使って初期化している。 Car car = new Car(); // 生成されたオブジェクトを形作るため、値を代入していく。 car.carType = "スポーツタイプ"; car.bodyColor = "赤"; car.size = 10; // 表示 System.out.println(car.carType); System.out.println(car.bodyColor); System.out.println(car.size); } }
Car car = new Car();
の一文ですが、これはどういったことを意味しているかというと、
「Carクラス(型)のcarという参照型変数を宣言します。コンストラクタCar()を使ってcarオブジェクトを初期化します。そして、new演算子を使ってcarオブジェクトをメモリ領域に確保します」
という意味です。
めちゃくちゃ細かく説明しましたが、これがすごく大事だと思います。
特にオブジェクト変数は参照型だということが重要な気がします。
コンストラクタを一応Car(){}というように書いていますが、これは必要ありません。
なくてもコンパイルも通るし、実行も出来ます。
なぜかというとJavaコンパイラが気を利かせてくれてコンストラクタを用意してくれるのです。
なんて賢いのでしょう。
コンストラクタを宣言、定義しなかった場合、Car(){}というようなコンストラクタがあるものとして勝手に用意してくれるのです。
コンストラクタを追加する
次にコンストラクタを追加してみましょう。
Car(String carType_, String color_, int size_) { carType = carType_; color = color_; size = size_; } Car(String carType_, String color_) { carType = carType_; color = color_; size = 15; }
このようにコンストラクタに引数を与えていきます。
このようにコンストラクタを定義すると、コンパイラが自動的に作ってくれたとりあえずのコンストラクタCar(){}は使えなくなります。宣言すれば使えるようになるのですが、自動的にコンストラクタは作られなくなります。
ていうか、同じコンストラクタ名が2つありますがいいんでしょうか。
イインデス!
シグネチャが違えばいいのです。
シグネチャとはなんぞや。
シグネチャとはその名前とパラメータの型と引数の数を合わせたものです。
この場合ざっくり言うと、
- コンストラクタ名
- 引数の型
- 引数の数
この3つの要素が違っていればいいのです。
コンストラクタを使うとき、シグネチャにあったコンストラクタをコンパイラさんが選んでくれて、それで初期化を行うのです。
このようにクラスには複数のコンストラクタを用意することが出来ます。
この機能のことをオーバーロード(多重定義)と言います。
class Car { // インスタンス変数 String carType; String color; int size; // コンストラクタ1 Car(String carType_, String color_, int size_) { carType = carType_; color = color_; size = size_; } // コンストラクタ2 Car(String carType_, String color_) { carType = carType_; color = color_; size = 15; } } class CarTest { public static void main( String args[] ) { Car car = new Car(); car.carType = "スポーツタイプ"; car.color = "赤"; car.size = 10; // 表示 System.out.println(car.carType); System.out.println(car.color); System.out.println(car.size); } }
実際のコードだとこんなです。
ちなみにこれをコンパイルするとエラーが出ます。
理由はCar(){}というコンストラクタはもはやJavaコンパイラは自動的に用意してくれないからです。
コンストラクタの所にCar(){}を追加してやると通ります。
こんな感じです。
class Car { // インスタンス変数 String carType; String color; int size; // コンストラクタ1 Car(String carType_, String color_, int size_) { carType = carType_; color = color_; size = size_; } // コンストラクタ2 Car(String carType_, String color_) { carType = carType_; color = color_; size = 15; } // コンストラクタ3 Car(){} } class CarTest { public static void main( String args[] ) { // car1オブジェクトをコンストラクタ3を使って生成 Car car1 = new Car(); car1.carType = "スポーツタイプ"; car1.color = "赤"; car1.size = 10; System.out.println(car1.carType); System.out.println(car1.color); System.out.println(car1.size); // car2オブジェクトをコンストラクタ1を使って生成 Car car2 = new Car("セダン", "シルバー", 12); System.out.println(car2.carType); System.out.println(car2.color); System.out.println(car2.size); // car2オブジェクトをコンストラクタ2を使って生成 Car car3 = new Car("SUV", "黄色"); System.out.println(car3.carType); System.out.println(car3.color); System.out.println(car3.size); } }
コンストラクタだけでこんなに時間かかってしまった...
長くなりそうなので続きは次回です。