静的メンバ#
頭にstaticを入れるだけ。
下記の例は複数の人間で一つの財布を持っているようなイメージ。
この場合、それぞれのHumanインスタンスh1,h2がフィールドを持っているのではなく、Humanクラスがフィールドを持っているという考え方。
なので静的フィールドはクラス変数とも言われる。
public class Human{
     static int money=100;
}
public class Main{
     public static void main(String[] args){
          // 一つ目のインスタンスを作成
          Human h1 = new Human();
          // 二つ目のインスタンスを作成
          Human h2 = new Human();
          // h1.moneyクラス変数を書き換え
          h1.money=200;
          // h2.money変数を表示
          System.out.println(h2.money);
          // moneyはクラス変数だから200と表示されるはず
     }
}
静的メソッドはインスタンスを生成しなくても呼び出せる。
だから、上の例で言うと、いきなり
System.out.println(Human.money);
とか書いても大丈夫。
mainメソッドが静的メソッドなのもそういう理由。
カプセル化#
カプセル化を実現する一つの方法として、アクセス修飾子をクラスやメンバに付けて可視性を設定する。
- 
public:すべてのクラス
- 
protected:自分と同じパッケージに属するか、自分を継承したクラス
- 
packaged private(デフォルト):自分と同じパッケージに属するクラス
- 
private:自分自身のクラスのみ
public class Test{
     private int i=1;
     public void calc(int j){
          return this.i+j;
     }
}
getterとsetter##
フィールドはprivate、メソッドはpublicに設定し、getterとsetterで値を受け渡す方法の基本的な書き方。
public class Test{
    private int num;
    public int getNum(){
        return this.num;
    }
    public void setNum(int num){
        this.num = num;
    }
}
継承・実装#
- 継承:exetends
- 実装:implements
抽象クラスの頭に付けるabstractが取れるのは抽象部分がオーバーライドされ尽くした時。
継承(exetends)##
ここではInu ← Shibainuという継承関係。
なお、osuwariメソッドは抽象化されているのでShibainuクラスでオーバーライドされる必要がある。
public abstract class Inu{
    public void ote(){
        System.out.println("左手を差し出す");
    }
    
    public abstract void osuwari();
        // ここは何も書かない
}
public class Shibainu extends Inu{
    public void osuwari(){
        System.out.println("地面に座る");
    }
    public void mate(){
        System.out.println("ご飯を我慢する");
    }
}
public class Main{
    public static void main(Strgin[] args){
        Shibainu dog = new Shibainu();
        dog.ote();      // Inu由来メソッド
        dog.osuwari();  // Inu(←Shibainu)由来メソッド
        dog.mate();     // Shibainu由来メソッド
    }
}
多態性を利用して、
Inu dog = new Shibainu();
dog.osuwari();
ということもできる。
この場合、呼び出すことのできるメソッドはInuクラスが持っているものだけになる。
ゆえに、実際に生成されるインスタンスがShibainuでもdog.mateは呼び出せない。
osuwariメソッドが呼び出された場合は、Inuの方ではなく、Shibainuの方のメソッドが処理される。
こうした多態性を利用して、以下のような処理も書ける。
Inu[] dogs = new Inu[3];
Inu[0] = new Shibainu();
Inu[1] = new Akitaken();
Inu[2] = new Tosaken();
for (Inu d: dogs){
    d.osuwari();
}
「地面に座る」「寝る」「言うことを聞かない」など、同じmateメソッドでもクラスによってメソッドの中身が違う場合にとても便利。
継承に関してはコンストラクタに注意する必要がある。
superを使って明示的に引数を与えてやらないといけない時があるからだ。
ここで使うsuperは子クラスのメソッド内で親クラスのメソッドを呼び出すときのsuperとは別物と認識していた方がいい(これはthisでも同じ)。
実装(implements)##
クラスをインターフェイスにできる条件は2点。
- すべてのメソッドが抽象メソッドであること。
- 基本的にフィールドを一つも持たない。
「基本的に」とあるのは、public static finalが付いたフィールド(定数)だけは宣言が許されるため。ただその場合はpublic static finalは省略可にしてもいい。
classではなく、interfaceと宣言する。
public interface Animal{
    void run();
}
public class Neko implements Animal{
    void run(){
        System.out.println("4本足で走る");
    }
}
インターフェースは多重実装が許されるので
public calss Neko extends Mammal implements Animal, Organic{
    // MammalクラスとAnimalインターフェースとOrganicインターフェースを親に持つ。
}
こういう書き方もできる。
猫クラスは哺乳類クラスを親に持ち、動物と有機物のインターフェースを持つ、という感じ。あんまり上手い例ではない。
インターフェース・抽象メソッドの美点は
- オーバーライドを強制させられる。
- 意図しないインスタンス化が避けられる。
- 何もしないメソッドと明確に区別できる。
といったところ。
参考書籍#
[スッキリわかるJava入門第二版]
(https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BJava%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1-%E6%B8%85%E5%96%AC/dp/484433638X)
Pp.332-524
