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


名前空間、パッケージ

  • プログラミングでは、名前をつける作業が沢山ある。クラス名、フィールド名、メソッド名、インスタンス名(変数名)、等々。これらの名前を適切につけることはわかりやすいプログラムを書くことにおいて非常に重要。
  • 名前がかぶると困る。
  • 名前空間(Namespace)
  • Java言語における名前空間の仕組み: パッケージ
  • パッケージ名はユニーク(一意)なものをつける。ドメイン名を逆から記述するのが慣例。
  • 今回は「lesson05.ユーザ名」

NetBeansでパッケージを作る

ソースパッケージを右クリックして新規、Javaパッケージ選択。

Newpackage1

パッケージ名を入力。場所がソースパッケージになっていることを確認。

Newpackage2

ソース・パッケージの下にできていることを確認。

Newpackage3

パッケージに対応してフォルダ(ディレクトリ)ができていることを確認。

Newpackage4

パッケージに所属するクラスを定義する

Newclass

  • パッケージのフォルダ内にクラスファイル(.java)を作成する。
  • パッケージ宣言を記述する。

同じパッケージに所属するクラスから使う

Bookクラスと同じようにMainクラスを作って、そこからBookクラスを使ってみよう。

Mainクラスにもpackage宣言がついたくらいで、これまでと特に違いはない。

違うパッケージに所属するクラスから使う

デフォルトパッケージにLesson05クラスを作成し、その中のmainメソッドから先ほどのBookクラスを使ってみよう。

違うパッケージから使うには、単にクラス名ではなく「パッケージ名.クラス名」で記述する。クラス名だけで使えるのは、同じパッケージに所属する(あるいはデフォルトパッケージに所属している)クラス。

ただし、まだこの状態ではエラーが出る。パッケージが異なるクラスからのアクセスには制限がかかっているからである。

アクセス修飾子

クラスの利用に関して制限をかけることができる。実は何も指定していない場合でも制限がかかっている。この利用の制限を設定するのが「アクセス修飾子」である。

アクセス修飾子の意味は4種類ある。とりあえず重要なのはpublicとprivate。

  • public
  • private
  • なし(つけない)
  • protected

どのような意味があるかは教科書を参照しよう。今回関係があるのは、「パッケージが同じ場合」と「パッケージが違う場合」について。

アクセス修飾子をつける対象はクラスとメンバー(フィールドとメソッド)。

先ほどのLesson5.javaのコンパイルエラーをなくすには、

  • Bookクラスを使うからclass Bookにpublicをつける。
  • コンストラクタを使うからコンストラクタにpublicをつける。
  • printInfoメソッドを使うからprintInfoメソッドにpublicをつける。

というように修正すれば良い。(注: このように「利用する側の都合」で「呼び出される側」を修正する、というのは設計がうまくいっていないことなので、あまり良くない。本来は、利用されるケースを想定してアクセス修飾子を適切に設定する)

これで、Lesson05.javaはコンパイルできるようになった。

ついでに、フィールドにはアクセスできない(例えば、book.price = 1000;等はエラーになる)ことを確認しておこう。

import

別のパッケージに所属しているクラスを使うには「パッケージ名.クラス名」とすれば良い。ただ、長くて面倒。

importを使うと、「パッケージ名.」を省略することができる。

import lesson05.d00000.Book;としておけば、このファイル内で「Book」と出てきたら、それは「lesson05.d00000.Book」という意味になる。

よくある質問

Q: パッケージに階層構造(包含関係)は?

A: ない。格納する場所(ソースコードの置き場所)は階層構造になるけど、各パッケージはなんの関係もできない。例えば「lesson05.p」と「lesson05.p.q」に包含関係は(見た目はありそうだけど)ない。

メソッド


メソッドとは(復習)

  • メソッドとはC言語の関数のような、「処理がまとめられたもの」である。
  • メソッドはクラスの中に作られる。
  • メソッドを実行するときに値を渡すことができる。その値のことを引数という。
  • メソッド内では、引数以外にも、インスタンスにあるフィールドも使うことができる。もちろんメソッド内で作った変数も使える。
  • メソッドの処理結果(値)を呼び出し元に返すことができる。その値を戻り値(返り値)という。

メソッドの例

Bodyクラスを題材にメソッドの実装例を見ていこう。実装したBodyの利用例も参照すること。

引数がなくて返り値がある

returnで返り値を指定する。

引数が1つで返り値がない

返り値がない場合は返り値の型の代わりに「void」と書く。

引数が2つで返り値がない

引数が複数の場合は「,」で区切る。

引数の名前がフィールドとかぶる場合、単にその名前を書くと引数の方が使われる。このような状況でフィールドの方を使うには「this.フィールド名」とする(教科書P.98)。

コンストラクタ

コンストラクタは「インスタンス化のときに実行されるメソッド」である。

例えば、これまではインスタンスを作成した後にフィールドに値を代入していたが、インスタンス化と同時に値を代入できるようなコンストラクタを定義してみよう。

コンストラクタの定義の注意点(普通のメソッドとの違い)は以下の2点。

  • コンストラクタの名前はクラス名と同じにする。自由につけられるわけではない。言い換えると、クラス名と同じ名前のメソッドはコンストラクタである。
  • コンストラクタには返り値がないので、返り値の型は記述しない。voidも書いてはいけない。

このコンストラクタを使ってインスタンスを作るには次のようにする。

ただし、この状態(コンストラクタを1つ定義した状態)でコンパイルしようとすると、Bodyクラスを呼び出しているクラス(Lesson03やLesson04)がエラーになってしまう。これは、「new Body()」に対応したコンストラクタが用意されていないからである。

「new Body()」に対応したコンストラクタも定義しよう。ここでは、乱数で身長と体重をセットすることにする。

これで、「new Body()」も使えるようになった。

そもそも、これまではなぜコンストラクタを定義していないのに「new Body()」でインスタンス化できていたのだろうか?それは、コンストラクタを1つも定義しない場合は、デフォルトコンストラクタという何もしないコンストラクタが生成されていたからである(教科書P.76)。デフォルトコンストラクタは、「コンストラクタを1つも記述しない場合」にだけ生成されることに注意すること。

クラスの基礎


クラスとは

  • データと処理をまとめたもの(教科書P.58)
  • 構造体に関数がついたもの(C言語がきちんとわかっている人向けの説明)
  • 型の定義
  • etc..

クラスはメンバーによって構成される。メンバーにはフィールド(データ、変数)とメソッド(C言語における関数)の2種類がある。

身体データ(身長と体重)からBMIを計算するプログラムを作ってみよう(ソースコード全体

クラスを使わない例

クラスを使う例

まずはクラスを作る(定義する)。まずは身長と体重を格納するフィールドだけのクラスを考えよう。

  • クラス名はBodyとする。クラス名は英語の大文字から始めることに注意。
  • weightとheightというフィールドを持つ。

クラスは「型の設計図」なので、設計図から実体を作る必要がある。その実体のことを「インスタンス」という(教科書では「オブジェクト」という言葉を使っている「オブジェクト」は文脈によって意味が違ったりするので本講義では「インスタンス」という言葉を使う)。クラスからインスタンスを作ることを「インスタンス化」という。

mainメソッドの中でBodyクラスをインスタンス化しよう。インスタンス化はnew演算子で行う。

インスタンスのフィールドは「インスタンス名.フィールド名」で利用することができる。それぞれのフィールドに値を代入してみよう。

これでタローのデータをフィールドに格納することができた。クラスを使わない例と同様にBMIを計算できる。ジローについても同様。

次にBMIを計算するメソッドをBodyクラスに加えてみよう(5-9行目)。メソッド名はgetBmiとする。メソッドからはフィールドにアクセスすることができる(C言語における「グローバル変数」のように見えるが、クラス内でならアクセスできるということと、インスタンスごとにフィールドができるという点で大きく違う)。

メソッドを使ってBMIを取得するには、例えば、次のよう呼び出すことができる。フィールドと同様に「インスタンス名.メソッド名(引数)」で呼び出せる。

最終的に表示するコードは次のようになる。

ポイント

  • クラスは設計図で、設計図から実体(インスタンス)を作る必要がある。
  • クラスはメンバーからなる。メンバーにはフィールド(データ、変数)とメソッド(処理、C言語における関数)がある。
  • インスタンス化はnew演算子で行う。
  • インスタンスのメンバーを使うにはドット演算子を使う。

Lecture03_main.png

変数、演算子、制御文


C言語との違いを中心に。詳しくは教科書を参照すること。

注: 「だいたい同じ」とは「(些細な)違いがある」ということなので全く同じと思わないこと。

変数

数値

C言語において、数値を格納する変数の型はint、long、float、double。Java言語でもだいたい同じ。

文字(単独の文字)

C言語で文字はchar型を使う。文字をシングルクォーテーションで囲むことによって文字を表現する。

これで、変数vには文字「a」が代入される(正確には文字「a」の文字コードである97が代入される。つまりcharは整数型)。

Java言語でもだいたい同じ。

文字列(複数の文字)

C言語ではchar型の配列として扱う。

Java言語ではString型を使う。

boolean型(論理型)

C言語では、真偽を表すのにint型を使い、真が0以外、偽が0としてきた。

例えば、

とした場合、aには0が格納される。

Java言語には真偽を表すboolean型がある。boolean型は値としてtrue(真)かfalse(偽)をとる。

論理演算はC言語と同じ。

型の種類

Java言語の型は、大きく2種類に分類される。

  • プリミティブ型
  • 参照型(クラス型)

ここまで紹介した型のうち、String型が参照型で、それ以外はプリミティブ型。とりあえず、ここでは「2つの種類がある(違いがある)」ということを覚えておくこと。

変数の宣言

C言語では変数の宣言は関数の最初で行う(最近のC言語ではそうでもない)。Javaでは関数(メソッド)の最初じゃなくても良い。

演算子

演算子とは「演算を表わす記号」のこと。

C言語とだいたい同じ。

演算子によって、被演算子(演算が作用する対象)として使える型が違うことに注意すること。

  • 算術演算子
  • 代入演算子
  • インクリメント演算子、デクリメント演算子
  • 比較演算子
  • 条件演算子
  • 論理演算子
  • キャスト演算子
  • ビット演算子

どんな演算が行われているか?演算の結果がどうなるか?を理解しよう。

制御文

Java言語の制御文は条件の判定にboolean型を使う(C言語は0かそれ以外かを判定する)。これ以外はC言語とだいたい同じ。

制御文の記述に関する注意: かっこは省略するな!ただ「省略できる」ということは知っていなければならない。

  • if else
  • for
  • while
  • break
  • continue
  • switch

NetBeansで「hello, world」


プロジェクトを作る

新規プロジェクト

新規 Javaアプリケーション

MyFirstProject 1

クラスを作る

MyFirstProject 2

New Javaクラス

メインメソッドを書く

実行する

MyFirstProject NetBeans IDE 8 1 と NetBeansでHello World

Spring Bootによるウェブアプリ開発の基礎(5)


永続化(永続性を保つ事)について。

計算機科学における永続性(英: Persistence)は、データを生成したプログラムが終了してもそのデータが存続する特性を指す。この特性がない場合、データはメモリ上にのみ存在し、コンピュータのシャットダウン時など、メモリの電源が切られた時点で消失する。(Wikipedia: 永続性より引用)

Javaアプリケーションにおける永続化の方法

  • ファイル操作を行うAPI(クラス)を用いる。[教科書6章]
  • JSONで保存: Jackson
  • リレーショナルデータベースに保存
    • JDBC: Javaプログラム内でSQLを構成・実行する
    • JPA (Java Persistence API): JavaにおけるO/Rマッパーの標準的な仕様
  • リレーショナルデータベース以外のデータベースに保存
  • etc…

Spring Bootではデータの永続化のために、JdbcTemplate(JDBCを簡単に使える機能)やSpring Dataが利用できるようになっている。

テキストファイルの読み書き

PersistenceSampleController.javaのloadTextメソッドとappendTextメソッド

JPA

  • build.gradleに追加
  • Memo.java: エンティティーを作成する。
  • MemoRepository.java: JpaRepositoryを継承してリポジトリを作成する。
  • PersistenceSampleController.java
    • @AutowiredでDIする
    • findAllで取り出す
    • saveで保存

Spring Bootによるウェブアプリ開発の基礎(4)


ここまでのまとめ。

コントローラ

  • @Controllerアノテーションが付加されたクラスがコントローラになる。
  • @RequestMappingアノテーションで対応するパス(URLのホスト部分より後)を指定する。クラスとメソッドにそれぞれに付加することができる。「クラスに付加された値」+「メソッドに付加された値」が対応するパスとなる。例えばクラスに「@RequestMapping(“/form”)」、メソッドに「@RequestMapping(“text”)」と付加されていた場合、そのメソッドが対応するパスは「/form/text」となる。
  • 各メソッドの返り値はString型とし、テンプレートのルートパス(src/main/resources/templates)からの相対パス(ファイル名)を返すようにする。「.html」は省略する。例えば、「return “form/text”」とした場合、「src/main/resources/templates/form/text.html」がテンプレートとして使われるようになる。
  • テンプレートに値を渡したい場合、ModelMap型のインスタンスにaddAttributeメソッドを使って値を保存する(とテンプレートで取り出すことができる)。
    キーと値のペアで保存する。ModelMap型のインスタンスは、メソッドの引数として指定することで取得することができる。
  • フォームからパラメータを受け取りたい場合は、メソッドの引数として指定し@RequestParamアノテーションを付加する。カッコ内はname属性で指定された値を指定する。

ビューテンプレート

  • テンプレートはThymeleafで記述する。
  • テキストノード(タグで囲まれた部分)にコントローラから受けとった値を埋め込むには、th:text属性をにキーを指定すれば良い。例: <タグ th:text=”${キー}”>埋め込まれる場所</タグ>
  • フォームで値を送りたい場合は、formタグを用いる。action属性で、送信先のURL(パス)を指定する。コントローラにおける区別のためにname属性を指定する。

フォームのサンプル

Spring Bootによるウェブアプリ開発の基礎(2)


HTMLフォームでデータを入力しよう!

後で書き直す。

  • formタグ、action属性、method属性
  • inputタグ、name属性
  • buttonタグ、type属性

他のトピックス。

  • selectを使うには?
  • radio、checkboxを使うには?
  • hiddenの使いどころ。
  • デフォルト値は?
  • ファイルのアップロードは?
  • GETとPOSTの違い
  • etc…

Spring Bootによるウェブアプリ開発の基礎(1)


本当はきっちり解説したいけど時間が足りないので、とりあえず動かすための最低限なポイント解説。

Gradle

Gradleはビルドツールの1つで、Androidアプリの開発でも使われるなど、メジャーになりつつある(すでにメジャーである)。

ポイント: Gradle以外にも色々あるけど、Gradle使っとけば多分大丈夫。

処理の流れ

Mvc

SpringのWeb MVCにおける処理の流れ(http://docs.spring.io/spring/docs/4.0.5.RELEASE/spring-framework-reference/html/mvc.html#mvc-servletより引用)

フロントコントローラがリクエストを適切なコントローラに渡し、コントローラが出力するデータをビュー(テンプレート)が表示するという仕組み。

ポイント: コントローラとテンプレートを用意すれば、ブラウザにページを表示させることができる。

アノテーション

クラスやメソッド、パッケージに対してメタデータとして付加情報を記入する機能(Wikipedia: アノテーションより)

大抵は「付加情報を記入する」だけではなく、アノテーションプロセッサによって様々な処理がなされる。Spring Bootでは、コントローラを作る時にアノテーションを使う等、様々なところで利用する。

ポイント: Spring Bootによるウェブアプリ開発ではアノテーションを良く使う。

コントローラの作成

  • クラスに@Controllerアノテーションをつけることで、このクラスがコントローラとして扱われる。
  • @RequestMappingアノテーションで、どのURLを対象とするかを指定する。
  • メソッドの戻り値はString型で、テンプレートのファイル名(拡張子は除く)を指定する。
  • メソッドの引数にModelMap型を加えると、テンプレートにモデルを渡すためのオブジェクトを得ることができる。addAttributeメソッドでキーと値を指定する。

ポイント: コントローラでは、URLに対応したメソッドを作る。メソッドはテンプレートを指定する。

テンプレートの作成

テンプレートエンジンとして標準ではThymeleafが使われる。

# Spring Boot 1.3.6ではThymeleaf 2.1.4(最新版ではない)が使われることに注意。

src/main/resources/templatesに作成する。

  • (Thymeleaf 2.1.4では)well-formedなXML文書でなければならないので注意する。つまり「タグは開始タグと終了タグを記述する(省略できない)」と「空要素(単独で現れるタグ、例えばhrタグ)はスラッシュをつける(例:<hr/>)」を守ればよい。
  • xmlns属性でThymeleafで使うプレフィックスを指定する。
  • th:text属性で、その要素のテキストノードに値を設定できる。
  • th:text属性では「${key}」とする。keyにはコントローラで指定したModelMapのキーを指定する。

ポイント: テンプレートでは、コントローラから送られてきたモデルをどこに表示するかをHTMLで記述する。