プログラミングド素人のデザイナーがJava入門してみた_その5


前回までのあらすじ

プログラミングド素人のデザイナーがJava入門してみた_その4

  • クラスの使い方がわかった

教科書

ドットインストールさまさま

パッケージとアクセス修飾子

  • パッケージとは関連するクラスをまとめるもの
    • 名前の衝突を避けることができる。
    • 他の人と被らないように、ドメインを逆から読んだものをつけるのが一般的
  • アクセス修飾子とは、パッケージに含まれるクラスやメソッドなどに対し、アクセスを許可する範囲を指定するもの

クラス(Top level)に対する修飾子

  • 2種のアクセス修飾子がある
public package private(何も書かない)
どこからでもアクセス可能 同じパッケージからのみ呼び出せる
  • アプリの起点となるmain()メソッドを含むクラスは必ずpulicとする
  • javaファイル1つにつきpublicなクラスは1つまでしか持つことができない

メソッド、フィールドに対する修飾子

  • 4種のアクセス修飾子がある
public package private(何も書かない) private protected
どこからでもアクセス可能 同じパッケージからのみ呼び出せる 同じクラスからのみ呼び出せる 同じパッケージ、もしくは別パッケージであってもサブクラスであれば呼び出せる
  • アプリの起点となるクラスに含まれるmain()メソッドは必ずpublicとする
  • フィールドは基本的にprivateとし、不用意に外部からアクセスされないようにするのが一般的
    • 別途メソッドを作成しアクセスコントロールをしていく

パッケージを作成

  • 結局のところ、パッケージ管理とはディレクトリでjavaファイルをまとめること
  • パッケージ名と対応する形でディレクトリを作成し、それぞれ適切な階層へ配置する
com
  ┗━hoge
      ┗━myapp
          ┣━model
          ┃   ┣━Fuga.java //package com.hoge.myapp.model
          ┃   ┗━Piyo.java //package com.hoge.myapp.model
          ┗━MyApp.java //package com.hoge.myapp

javaファイル側の記述

  • javaファイルの冒頭に、属するパッケージ名を宣言する
package com.hoge.myapp // com/hoge/myappの階層に配置されたjavaファイル、という感じ
  • 他のパッケージからクラスを参照する際は、javaファイルの冒頭でクラスをimportする
import com.hoge.myapp.Class //パッケージ名に続けてクラス名を記述
  • 一括でimportするには*(ワイルドカード)を使う
import com.hoge.myapp.* //com.hoge.myapp配下のクラスをすべてimportする

コンパイル

  • 起点となるmain()を含むjavaファイルをコンパイルすれば、関連する他のjavaファイルも芋づる式にコンパイルされる

getterとsetter

  • フィールドへのアクセスは不用意な操作を避けるため、専用のメソッドを通して行うことが一般的
    • hoge.huga的なアクセスはしないということ?
  • フィールドのアクセス修飾子は原則privateとし、クラス内からのみアクセスできるようにする
  • 今回の場合"クラス内からのみ"というのはクラスに登録されたメソッドからならアクセスできるということ
  • フィールドを呼び出すメソッドをgetter、フィールドの値を書き換えるメソッドをsetterという
    • 慣習的にそれぞれgetHoge,setHogeというメソッド名にする
class User{
  private String name;//アクセス修飾子はprivate
  private int score;//同じくprivate

  public User(String name, int score){//コンストラクタ
    this.name = name;
    this.score = score;
  }

  //★getter★_このメソッドを通してフィールドの値を呼び出す
  public int getScore(){//フィールドの値を返すので、型を明示しておく
    return this.score;
  }

  //★setter★_このメソッドを通してフィールドの値を変更する
  public void setScore(int score){
    if (score > 0){//値が0より大きい場合のみ変更を行う、といった条件も付与できる
      this.score = score;
    }
  }

}

public class HelloWorld {
  public static void main (String[] args){

    User tom = new User("Tom",65);//インスタンス化
    System.out.println(tom.getScore());//65
    System.out.println(tom.score);//privateのフィールドへのアクセスのためコンパイルエラー    
  }
}

@iwashi0830はこう思った

  • 大規模な実装をしたことがないからか、アクセス修飾子は全部publicでよくね?と思ってしまう
    • まあ安全性を確保するためには必要なことなんだろうけど
  • パッケージ管理はディレクトリで管理するというシンプルな考え方でわかりやすい
  • フィールドにアクセスするためにメソッドを用意するというのも新鮮
  • privateの"クラス内でのみアクセス可能"の挙動をちゃんと覚えておこう