新入社員でJavaを勉強し始めたみなさんに対し、
不定期で更新していきたいと思います。
今回のテーマは「クラスの書き方」です。
クラスの基本形
まずは、クラスの基本形です。例として「人」を表すクラスを考えてみましょう。
public class Person {
/** 氏名 */
private String name;
/** 年齢 */
private int age;
/**
* コンストラクタ
* @param name 氏名
* @param age 年齢
*/
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 年齢の取得
*/
public int getAge() {
return this.age;
}
/**
* ひとつ歳をとる
*/
public void countUpAge() {
this.age++;
}
/**
* 自己紹介
*/
public void introduction() {
System.out.println("こんにちは、私は" + this.name + ", " + this.age + "歳です。");
}
}
クラスを構成する要素
今回紹介したクラスに限らず、
クラスには大きく分けて3つのセクションに分けて記載を行います。
public クラス名 {
フィールド
コンストラクタ
メソッド
}
フィールド
Personクラスでは、以下の部分を指します。
/** 氏名 */
private String name;
/** 年齢 */
private int age;
フィールドは、そのクラス内ならどこでも使用できる変数です。
つまり、同じクラス内であれば、違うメソッドからでも同じ変数を参照することができるようになります。
コンストラクタ
Personクラスでは以下の部分を指します。
/**
* コンストラクタ
* @param name 氏名
* @param age 年齢
*/
public Person(String name, int age) {
this.name = name;
this.age = age;
}
ちなみに、このPersonクラスを初期化する場合には、以下のようなコードになります。
Person person = new Person("太郎", 10);
このように、コンストラクタは開始時に特定の処理を実行するために使用します。
オブジェクトの初期化を行う際には、必ずコンストラクタが呼ばれますので、
フィールド値の設定などに利用されることが多いです。
メソッド
Personクラスでは以下の部分を指します。
/**
* 年齢の取得
*/
public int getAge() {
return this.age;
}
/**
* ひとつ歳をとる
*/
public void countUpAge() {
this.age++;
}
/**
* 自己紹介
*/
public void introduction() {
System.out.println("こんにちは、私は" + this.name + ", " + this.age + "歳です。");
}
メソッドには実行する処理を記載します。
メソッドのキホン
メソッドは、一つの処理をまとめるために利用します。
全ての処理をひとつにまとめることができますが、
手順ごとに別に分けた方が見る人もわかりやすいですよね。
メソッドには名前をつけることができますので、
用途や取り扱う対象の変数などによってうまく分けていくことが大事です。
基本的な書き方
メソッドの基本形は以下の通りになります。
アクセス修飾子 戻り値の型 メソッド名(引数1, 引数2, ...) {
処理
return 戻り値;
}
数学の時間に、「関数」という単語を聞いた記憶はありますでしょうか。
f(x) = x + 1
これをJavaのメソッドに直すと、以下のような記載になります。
public void func(x) {
return x + 1;
}
どちらも、「引数 x に 1 を加算して返却する」ものです。
実は、「メソッド」と「関数」はとても近い存在で、ほぼ同じものを指します。
例えば、C言語では以下の記載を関数と呼んでいます。
int func(x) {
return x + 1;
}
Javaをはじめとするオブジェクト思考の言語では、クラス内に記載された関数の記載をメソッドと呼んでいます。
関数とメソッドの厳密な違いについては、また別な機会に解説したいと思います。
アクセス修飾子
アクセス修飾子とは、そのフィールドやメソッドがどの範囲でアクセスできるかを定義しており、
publicやprivateで指定しています。
publicを付与するとクラス外からもアクセス可能となり、
prvateとすると、そのクラス内からしかアクセスできなくなります。
戻り値
例として、以下の場合にはint(数値)を戻り値とするgetAgeというメソッドを定義しています。
public int getAge() {
return this.age;
}
この戻り値の型を指定することで、このメソッドの呼び元は、
「このメソッドはint型を返却するんだな」と認識することができます。
// このようにpersonの年齢を取得できる
int himAge = person.getAge();
// これは型が一致せずエラーになります
String himAge = person.getAge();
戻り値がない場合
戻り値がない場合には、戻り値の部分に「void」という文字を設定します。
voidは「空・何もない」ということを表します。
戻り値にvoidを指定した場合には、何も値を返却しないためreturnの記載が不要となります。
/**
* ひとつ歳をとる
*/
public void countUpAge() {
this.age++;
// ここにあるべき「return」を省略することができる。
}
引数とオーバーロード
さて、今度は「氏名を設定するメソッド」を足してみましょう。
名前には姓と名がありますし、ミドルネームがある場合もあります。
それぞれに対応した氏名設定のメソッドを作ってみましょう。
/**
* 姓名対応のメソッド
* @param lastName 姓
* @param firstName 名
*/
public void setName(String lastName, String firstName) {
this.name = lastName + " " + firstName;
}
/**
* ミドルネーム対応のメソッド
* @param lastName 姓
* @param firstName 名
* @param middleName ミドルネーム
*/
public void setName(String lastName, String firstName, String middleName) {
this.name = firstName + "・" + middleName + "・" + lastName;
}
さて、これをそれぞれ実行してみましょう。
person.setName("佐藤", "太郎");
// -> 「佐藤 太郎」
person.setName("佐藤", "クリスティーナ", "太郎");
// -> 「太郎・クリスティーナ・佐藤」
このように、同じ「setName」という名前のメソッドながら、違う処理を行うことができます。
これを、「メソッドのオーバーロード」と呼びます。
オーバーロードは、同じ目的でありながら複数の引数をもつ場合に活用することができます。
さいごに
「クラスの中に色々とあってよく分からない」という方も結構いらっしゃると思います。
ですが、実は覚えるべきルールはそんなに多くありません。
今回紹介した3つの要素に分けて考えるだけでも、ソースコードがより読みやすくなります。
いきなり全部を読み取ろうとせず、
少しずつ分離して考えていくことが理解への第一歩ではないでしょうか。