2018年03月15日

師匠のJava道場~第7回・クラスについて知るのじゃ!(後編)

師匠T:さて、今月も始まったの。師匠のJava道場。
 今回は、アクセス修飾子と、文字列について学び、そしていよいよクラスを実際に作ってみようと思う。
 準備はよいか?

弟子D:はい、師匠!

師匠T:うむ。弟子も燃えておるようじゃの。いいことじゃ。それでは始めるぞ!

▽アクセス修飾子とはなんぞや?▽

師匠T:まずは、アクセス修飾子からじゃ。これは、クラス、メソッド、変数が、他所からアクセスできるかどうかを示したものじゃ。これには、次の四つがある。
・public……どこからでもアクセスできる
・protected……自分のファイルからはどこでもアクセス可能。他所のファイルからは、サブクラスからのみアクセス可能。
・private……自分のいるクラスからのみアクセスできる

師匠T:例えば、sisyoというクラス内に、privateで宣言された変数があった場合、この変数は、sisyoクラスの中からしか、アクセスすることはできぬのじゃ。

弟子D:一方、publicで宣言された場合は、どこからでもアクセスできるというわけですね? ……あれ? 師匠、四つあると言っておきながら、実際には三つしかありませぬが。ははーん、師匠ももうボケ……いてっ。

師匠T:たわけが。わしはまだまだ若い。アクセス修飾子を省略した場合も含むから、四つというわけなのじゃ。アクセス修飾子を省略した場合は、自分のファイルからなら、どこからでもアクセスできる。他のファイルのクラスなどからはアクセスできぬのじゃ。

弟子D:なるほど。それで師匠。protectedのときに述べられているサブクラスとはなんぞや?

師匠T:うむ。それは、あるクラスをもとにして作られたクラスのことじゃ。ちなみに、そのもとになったクラスのことは、スーパークラスという。

弟子D:ふむふむ。

師匠T:このあるクラスを基にして違うクラスを作ること……継承というがの……については、別の機会に説明する。今は、サブクラスは、スーパークラスから作られたクラスであることを覚えておけばよい。

弟子D:ということは、protectedで宣言された場合は、アクセスするクラスが、別ファイルにあるクラスから作られたサブクラスであれば、アクセスできる、ということですね。

師匠T:うむ、その通り。さて、ついでにstaticについても説明しておこう。一般的に、変数やメソッドなどにアクセスするためには、事前にそのクラスを実体化……これをインスタンス化という……させる必要があるが、staticがつけられたクラス、メソッド、変数は、インスタンス化させてなくてもアクセスすることができるのじゃ。

弟子D:おぉっ、それは便利ですね!

師匠T:じゃが、そんな便利そうなstaticにも一つ問題がある。staticで宣言されたメソッドからは、staticでないメソッドをアクセスすることはできぬのじゃ。

弟子D:なるほど……。

師匠T:なお、アクセス修飾子やstaticは、クラス名やメソッド名、変数名の前に、次のようにしてつける。

----------
[アクセス修飾子][static][型]名前
例:
public int a;
private static long b;
----------

師匠T:それと、protectedは、メソッドや変数にしか使うことができぬので、注意すること。

▽文字列の正体とは!?▽

師匠T:さて。いよいよ文字列についてじゃ。

弟子D:はい、師匠! 確か前、「文字列は特別で、変数では扱えない」と言っておられましたが。

師匠T:うむ。それはなぜか、いよいよ語るとしよう。実は文字列は……。

弟子D:ごくり。

師匠T:クラスであり、オブジェクトであるからなのじゃ!!

弟子D:な、なんと!?

師匠T:文字列は、Stringクラスというクラスのインスタンスなのじゃ。そして、この場合、文字列を変数に格納するというのは、実際には、その変数と、文字列……Stringクラスのインスタンスとを結びつける作業なのじゃ。

弟子D:つまり、入れているわけではなく、変数には文字列へのリンクが張られている、と?

師匠T:うむ、そのようなイメージで問題なかろう。それゆえに、この文字列と文字列変数には、いくつか、普通の変数と違う振る舞いや制限があるのじゃ。

弟子D:それはどのような?

師匠T:まず一つ。文字列は変更させることができない。

弟子D:ええええ!? だって、

----------
String s = "abc";
s = "def";
----------

弟子D:ってやったら、ちゃんと動きますよ?

師匠T:うむ。ちゃんと動く。だがそれは、abcという文字列が変わったからというわけではない。

弟子D:???

師匠T:おぬし、さっき言っておったであろうが。変数には何が張られている?

弟子D:あっ! 「文字列のリンク」!

師匠T:その通り。つまり、上の文からすると、書き換えているように見えるが、実際には、defという文字列(実際には、Stringクラスのインスタンス)を新しく作って、変数sからのリンクを、最初のabcという文字列から、新しく作られたdefという文字列に張りなおしているのじゃ。

弟子D:な、なるほど……。

師匠T:話を戻すぞ。そして二つ目。文字列変数は、通常の方法では比較することはできぬ。そのためには、Stringクラスに備わっている、equalsというメソッドを使う必要がある。使い方はこうじゃ。

----------
[文字列変数].equals(比較対象);
例:
s.equals("abc");
----------

師匠T:このメソッドは、文字列変数の中身が比較対象と同じならばtrueを返すぞ。なお、Stringクラスには他にも、文字列を扱うメソッドが色々とある。興味があるなら、Javaについての本やサイトを読むがよい。

弟子D:はい、師匠!

▽クラスを作ろう!▽

師匠T:さて、ではいよいよクラスを作ってみよう。今回は、fireメソッドを実行すると、「BAN!」と表示する、zakuクラスを作ることにする。

弟子D:はいっ!

師匠T:まずはクラス名の宣言からじゃな。どうするかは覚えておるか?

弟子D:え、えーとえーと……。

師匠T:こう書くのじゃぞ。改めて頭に刻みなおすがよい。

----------
[アクセス修飾子]class[クラス名]
----------

弟子D:ということは……

----------
public class Zaku {
----------

弟子D:こうですかね?

師匠T:うむ、その通り。次はコンストラクタじゃな。コンストラクタはこう書くぞ。覚えておるか?

----------
public クラス名(引数)
----------

弟子D:つまり、メソッド名が、クラス名と同じメソッドを作ればいいんですよね?

師匠T:うむ、その通りじゃ。さて、今回は引数はなしでいこう。とすると、こうなるぞ。

----------
public Zaku() {
----------

師匠T:コンストラクタの内容じゃが、"Stand Up!"と表示させることにしよう。ということで、さっきのと合わせて、コンストラクタはこうなる。

----------
public Zaku() {
  System.out.println("Stand Up!");
}
----------

師匠T:さて、次はfire……の前に、セッター、ゲッターのテストとして、弾数を表すint型の変数shotの内容を表示、および設定するゲッター『getShot』とセッター『setShot』も作るとしよう。

弟子D:変数shotは、どこで宣言すればいいんですかね?

師匠T:これまで学んだことと、セッター、ゲッターの意味から考えるのじゃ。セッター、ゲッターはそれを通して、変数の中身を変えるためにある。他方、変数の内容は、クラス内のセッター、ゲッターのどこからでもアクセスできるようにしなくてはならぬ。ということは?

弟子D:あっ! クラス変数として宣言しなくちゃならない、ということですね! ということは、public class Zaku {の下に書くのが正解なのでは? それも、privateとして。

師匠T:うむ、その通り。見事じゃ。その調子で、セッターとゲッターも作ってみるがよい。

弟子D:はい! えーと……こうでしょうか?

---------------------------------------
public int getShot() {
  return shot;
}

public void setShot(int inShot) {
  shot = inShot;
}
---------------------------------------

師匠T:うむ。ゲッター、セッターの両方とも、publicで宣言しておるな。正解じゃ。さて、本題のfireメソッドじゃが、これは簡単じゃな。

---------------------------------------
public void fire() {
  System.out.println("BAN!");
}
---------------------------------------

師匠T:完成したクラスのプログラムがこうじゃ。

-------------------------------------------
public class Zaku {
  private int shot;

    public Zaku() {
      System.out.println("Stand Up!");
    }

    public int getShot() {
      return shot;
    }

    public void setShot(int inShot) {
      shot = inShot;
    }

    public void fire() {
      System.out.println("BAN!");
    }
}
-------------------------------------------

師匠T:今回はここまで。次回は、クラスからいったん離れて、変数を扱ううえで重要なことの一つ、キャストについて説明する。復習、予習をしっかりしておくがよい。


※次の更新は、3月19日、URAURA Game Reviewの予定です。お楽しみに!
posted by 裏編 at 09:12| 師匠のJava道場 | 更新情報をチェックする