Java SpringBoot + Thymeleaf 画面を作成する ~ControllerからHTMLまで~

イントロダクション

前回はSpringBootでの開発セットアップを行いました。

前回の状態では、エラーページしか確認できませんでした。

これは、サーバーが起動していることを確認するという意味で、必要な確認なのですが。。。動かないのでは面白くありません。

SpringBoot + Thymeleafで画面を作る

毎度おなじみ、「ハローワールド」をやってみようと思います。

作成するもの

  1. Javaファイル(コントローラークラス)
  2. HTMLファイル(Thymeleaf使用)

コントローラークラスを作る

まずは、作成して動かすことに注力します。
プロジェクトを作成したら初めに「SampleWebAppApplication」というクラスが作成されていると思います。

このクラスがアプリケーションを起動するクラスです。しかし、このクラスはいじる必要がありません

Controllerがアプリを動かすために

自動生成された「SampleWebAppApplication」はアプリケーションを起動するためのクラスなので、本当にアプリを起動するだけなのです。

起動確認するときに、エラーページしか出ないのは表示するものが何もないからです。

それでは、早速コントローラークラスを作成します。まずは、ルールがあるのでそれに注意します。
先ほど自動生成されたクラス「SampleWebAppApplication」はパッケージ「com.example.demo」というパッケージに作成されています。

パッケージはウィンドウズでいうところの「フォルダ」に相当します。上に貼り付けているものは、パッケージを表示していいます。

一番上にある「src/main/java .... 」の部分はフォルダ構成上下のようになっています。

  1. プロジェクトのフォルダがあります。
  2. その中に、srcというフォルダがあります。
  3. 同様にmainというフォルダ
  4. javaというフォルダ
  5. そして、ここからが「パッケージ」と呼ばれるフォルダになります。「com」フォルダ
  6. 「example」フォルダ
  7. 「demo」フォルダ

このようにフォルダ構成が出来上がってるのですが、これを「パッケージ」と呼び下のように表現することで、どのファイルのクラスを参照するかわかるようにしています。
Javaのプログラムでいうと「インポート文」がそれにあたります。

import con.example.demo.*;

上のインポート文は「con.example.demo」パッケージにあるクラスを全てインポートするという意味です。

Controllerのみで動かす

パッケージに関して意味が分かったところで、上記で記載した「ルール」に関してお話ししたいと思います。
自動生成されたクラス「SampleWebAppApplication」よりも下のパッケージ内にコントローラーなどの読み込むクラスを作成するというルールがあります。

なので、今回作成するコントローラークラスはパッケージ「com.example.demo.controller」に作成することにします。
パッケージの作成方法は下のように行います。

  1. 作成するパッケージの親になるパッケージを右クリック※com.example.demoパッケージを右クリックしました。
  2. そして、「パッケージ」という文言が見つかればよいのですが、残念ながら表示されていませんので「その他」をクリックします。すると下のようなウィンドウが開きます。
  3. そこでパッケージを選択してやれば作成できるというところです。

さらに、ここからクラスも作成します。手順は上と同じですが、選択するものが「クラス」になります。

そして、ここでは「HelloController」というクラスを作成します。

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index(ModelAndView mav) {
        return "Hello World";
    }
}

<表示結果>

ここでは、HTMLの作成は必要がありません。

実は、上記の「@RequestMapping」アノテーションを付けたメソッドは返却文字列を指定した場合はHTMLになります。なので下のようにコードを変更してやると。。。

@RequestMapping("/")
public String index(ModelAndView mav) {
    return "<html>"
            + "<title>Hello World</title>"
            + "<body><h1>こんにちは</h1>"
            + "<p>~PGボックスより~</p>"
            + "</body>"
            + "</html>";
}

<表示結果>

このように表示できます。しかし、「もっとオシャレに!」「もっと機能的に!」ということを考えるとHTMLファイルを使用して動かした方が効率的です。

もちろん、ウェブデザイナーさんの協力を頂き、その実力を発揮してもらうならナチュラルなHTMLがベストです。JSPなどは専門外のはず。。。

HTMLを作成する

そこで「Thymeleaf」というフレームワークを使用します。これはコントローラーとHTMLを橋渡しするためのフレームワークです。
具体的に見ていきましょう。まずはHTMLをみてみましょう。

<!DOCTYPE html>
<html>
<head lang="ja" xmlns="http://www.thymeleaf.org">
    <meta charset="UTF-8">
    <title>Sample Index Page</title>
</head>
<body>
    <h1>Recommended index</h1>
    <p>おススメの漫画・アニメを検索できます。</p>

</body>
</html>

上のようなHTMLを作成します。この状態ではコントローラーとのやり取りがない状態です。
しかし、まずはこの状態で動かしてみます。作成したHTMLファイルは「src/main/resources/templates」フォルダの下に作成しましょう。

そして、コントローラーも書き換えます。

@RequestMapping("/")
public ModelAndView index(ModelAndView mav) {
    mav.setViewName("book");
    return mav;
}

<実行結果>

このように動いたところで、コントローラーから値を渡すことを考えます。

コントローラーからHTMLへ。。。

今回のJavaプログラムはサーバーサイド・プログラムなので(※クライアントでも動かすことができます。)サーバー側での処理を行うことができますが、クライアント(ブラウザ上)でのプログラムはJSとかHTMLに任せることになります。

なので、サーバーでの処理結果をクライアントに渡すにはちょっとテクニックが必要になります。
具体的には、以下の通りです。

  1. リクエストパラメータを使用する
  2. レスポンスに処理結果を埋め込む(渡す)

こんなことを言われても「???」となってしまう人は正常です。ご安心ください。

具体的に下のようなコードで処理の結果を渡します。プログラムは微妙に修正しています。
<Java>

@RequestMapping("/")
public ModelAndView index(ModelAndView mav) {
    mav.setViewName("book");
    mav.addObject("key", 12);
    return mav;
}

<HTML>

<!DOCTYPE html>
<html>
<head lang="ja" xmlns="http://www.thymeleaf.org">
    <meta charset="UTF-8">
    <title>Sample Index Page</title>
</head>
<body>
    <h1>Recommended index</h1>
    <p>おススメの漫画・アニメを検索できます。</p>
    <p th:text="${key}">ここに値が入ります。</p>

</body>
</html>

<実行結果>

赤枠で囲った部分がJava側からHTMLへ渡した値です。

とりあえずは、ここまでに致します。

でわでわ。。。

<<< 前回

Java SpringBoot セットアップ ~Eclipse All in Oneでやると早い~

SpringBootの開発 セットアップ

SpringBootのセットアップを行うのに、いろいろな手順があり、混乱するので(自分の行った中で)もっとも簡単な方法を記載します。

使用するIDE(開発ツール)はEclipseのAll in Oneです。

大まかな手順

  1. プロジェクトを作成するときにSpringBootのスタータープロジェクトを作成する
  2. プロジェクト作成時に、ThymeleafとDB(H2DB)とSpringWebを追加する
  3. プロジェクト作成後にPOMファイルを「Maven install」で実行する
  4. Mavenプロジェクトの更新

プロジェクトの作成

Eclipseを起動してから、下のようにプロジェクトを右クリックし「新規」をクリック以下の手順に従います。

  1. Springスタータープロジェクトを選択し、「次へ」をクリック

  2. プロジェクトの名前などを入力する。使用するJDKによって「Javaバージョン」の値を変更する
     ※JDK1.8であれば「8」を選択する

  3. 使用するDBやフレームワーク(ツール)を選択する、今回はDBに「H2DB」、画面の作成に「Thymleaf」を使用するのでそれぞれのチェックボックスにチェックを入れる
    そして、Spring Webにチェックを入れる

  4. 最後に完了を押下する

※画像には「MySampleWebbApp」とあったが、「SampleWebApp」プロジェクトを作成した形で手順を進めます。

作成したプロジェクトは下のような形でEclipseのプロジェクトエクスプローラー、もしくは、パッケージエクスプローラーに表示されるはずです。
作成後のプロジェクト名が「MySampleWebbApp」になっていますが、「SampleWebbApp」での作成も確認しています。

プロジェクトを作成したばかりの状態では、バックグラウンド処理で何かしらのインストールが走っているので、ちょっと待ちます。

最後にプロジェクトを右クリック、実行、Spring Bootアプリケーションをクリック
これだけで、セットアップは完了です。

そして、ブラウザを開き、http://localhost:8080 にアクセスします。
ここでは、エラーページしか出ませんが、Tomcat(Webサーバー)が動いていることを確認するのが目的なのでこれでよいのです。

Eclipseでウェブ開発を始める~Java Servlet 二歩目 Servletを動かす~

イントロダクション

前回はEclipseを使用して、JavaServletの起動環境を作成しました。

観光構築だけで、起動確認はしていなかったので、これを確認するところから始めます。

Servletを動かす

前回作成したサーブレットは下のようなもの(コード)です。

/**
 * Servlet implementation class SrvLesson1
 */
@WebServlet("/SrvLesson1")
public class SrvLesson1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public SrvLesson1() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

これを実行すると、下のような表示ができます。

「?????」と表示されているのは、文字コード(charset)が指定されていないからです。
これを指定するには下の王なコードを書きます。

response.setContentType("text/html; charset=UTF-8;");

そして、実行結果は下のようになります。

Tomcatについて

TomcatはWebコンテナ、APサーバーなどと呼ばれる分類に入る「サーバー」です。
サーバーは複数個所から、アクセスを受けて、それぞれのリクエスト(入力やボタン押下)に対する処理を行い、レスポンスという形で処理の結果をクライアントに返します。

絵にすると下のような感じです ※画力が。。。

コード解説

JavaServeltの実装にはいくつかのポイントになる部分があります。

  1. クライアントとサーバーの関係がある。
    クライアント(ブラウザ(IEやChrome, FireFox, Safariなど))とサーバー(Javaで作成したサーブレットが動くTomcatのようなアプリケーション)。クライアントはサーバーにリクエストを送信、サーバーはクライアントへレスポンスを送信する。

  2. HTMLのFormタグにある「action」属性にサーブレットを指定する。
    action="SukiriWeb2/SrvLesson1"などのように指定すると対象のURLに指定したサーブレットが起動する。

  3. レスポンスは、HTMLでブラウザに表示される。

コード内容

リクエストの種類には「GET」と「POST」があり、サーブレットに実装(オーバーライド)している「doGet()」と「doPost()」がそれぞれに対応する。
つまり。GETリクエストの時は「doGet()」POSTリクエストの時は「doPost()」が動く。

それぞれの処理の最後に「response.getWriter()」とあるが、これは返却するレスポンスに、返却する内容を追加するためのオブジェクトを取得するということです。

具体的には、PrintWriterクラスですが、このクラスにHTMLを書きこむことで、ブラウザに表示するHTMLを返却することができます。

つまりは、そのような仕組みになっている(フレームワーク化されている)ということです。

コードをいじってみる

返却する値を作成しているのは、サンプルにあるコードは下のようなものです。

StringBuilder build = new StringBuilder();
build.append("<!doctype html>");
build.append("<html>");
build.append("    <head>");
build.append("        <title>aaa</title>");
build.append("<body>はじめのサーブレット</body></html>");

そして、HTMLを返却するだけでなく今まで学習してきた処理を行うこともできます。

try {
    PreparedStatement pre = H2dbManager.getInstance().createPreparedStatement(SQLConst.INSERT_USER_TABLE);
    pre.setString(1, userName);
    pre.setString(2, passwd);
    pre.setInt(3, 1);
    if (pre.execute()) {
        throw new SQLException("ユーザー登録に失敗しました。");
    }
} catch (SQLException e) {
    // TODO 自動生成された catch ブロック
    e.printStackTrace();
    return false;
}

「一度書けばどこでも動く」というのがJavaのウリです(笑)

上の処理は、H2DBへのアクセスを行うための「H2dbManager」クラスを作成したので、そこからSQLを発行するために以下のようなことを行っています。

  1. PreparedStatementクラスを取得
  2. 実行するSQLの設定(パラメータを設定できるようにしている)
  3. パラメータの設定
  4. SQLの実行

ユーザー登録の処理です。詳細に関しては、以下に記載します。

H2DBManagerクラス

/**
 * プライベートコンストラクタ、H2DBのコネクションを取得する。
 * {@link H2dbManager#getInstance()}
 */
private H2dbManager() {
    try {
        Class.forName("org.h2.Driver");
        // 「~」はマイドキュメントを示す。
        con = DriverManager.getConnection("jdbc:h2:tcp://localhost/~\\workspace\\SukiriWeb2\\WebContent\\WEB-INF\\database");
        Statement stmt = con.createStatement();
        stmt.execute(SQLConst.CREATE_USER_TBL);
        stmt.execute(SQLConst.CREATE_ITEM_TBL);
        stmt.execute(SQLConst.CREATE_ITEM_TYPE_TBL);
    } catch (SQLException e) {
        e.printStackTrace();
        System.exit(-1);
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(-1);
    }
}

/**
 * このクラスのインスタンスを取得する。
 * @return H2dbManagerインスタンス
 */
public static H2dbManager getInstance() {
    if (instance == null) {
        instance = new H2dbManager();
    }
    return instance;
}

Eclipseでウェブ開発を始める~Java Servlet 初めの一歩~

イントロダクション

ウェブシステムを開発するのにPHPが広く使われていますが、Javaでもできます。
というかでかいシステム(業務用など)は大体Java言語で作成されたシステムが多いのです。

理由

Javaはスピードと安定性においてほかの言語(PHPなど)に比べて処理スピードが速いようです。
以下のサイトを参考にしました。

  1. PHP vs Java
  2. Node vs. PHP vs. Java vs. Go

ほかに、適当なサイトが見つからなかったもので。。。
ちなみに、2のサイトではGo言語が1位でした。しかし、こちらのサイトで処理の内容をおみてみるとJavaのプログラムはスピード向けの実装になっていない。。。

自分の、感想としては、簡単なコードで実装するのであればGoの方が速いと思いました。
まぁ、簡単なコードの方がよいのですが、実装方法に関してはその人のスキルになるので何とも言い難しですね。。。

Javaの魅力は、ほぼ大体のことができ、指定した言語を取り込む(C言語で書かれたコードをJava言語として実行する)ことや、
実行するOSから別のスレッドで他のアプリケーションを起動できたりします。

開発準備

気を取りなおして、Javaの開発を進めます。
まずは、インストールするものがあります。それはEclipseです。こちらのサイトからできます。

こちらから最新のものを選択してインストールしてください。
詳細に関しては、こちらのページに記載しています。

設定方法に関しては、こちらにあります

ウェブ開発を始める

具体的に・・・

下のようなイメージのアプリケーションを作成します。

・自分のPC上でアプリケーション・サーバーを動かす
・いつものブラウザで、アプリケーション・サーバーにアクセス
・指定したサーブレットクラスを動かす。
・新しいURLの指定し方やり方

環境構築(Eclipseのプロジェクト)

  1. プロジェクトを新規で作成する

  1. 作成したプロジェクトにフォルダーを追加します。
    「classesフォルダ」を作成し以下のようにビルドパスに追加する

  1. Serveltクラスを作成する

    /**
    * Servlet implementation class SrvLesson1
    */
    @WebServlet("/SrvLesson1")
    public class SrvLesson1 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    /**
     * @see HttpServlet#HttpServlet()
     */
    public SrvLesson1() {
        super();
    }
    
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }
    
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    }
  2. サーバーを追加する(Tomcat8.XXXX)

  1. 作成したプロジェクトをサーバーに追加する

  2. サーバーを起動する。

  3. 作成したサーブレットが動くことを確認。

まとめ

これが作成できたら、あとは、どのようなものを作成するのか考えていきます。
現状では、Javaでサーバー側のプログラム、サーブレット(サーバー処理)を実行できるような状態になっています。

仕組みとしては、「@WebServlet("/SrvLesson1")」で指定しているURL「/SrvLesson1」にアクセスしたときにこのサーブレットが動く状態です。
実際にURLにアクセスするときは下のような形で指定します。

「localhost:8080/プロジェクト名/指定しているURL」 => 「localhost;8080/SukiriWeb2/SrcLesson1」

まずは、一区切りということで。。。

でわでわ。。。

Java Basic 総復習編 〜基本と基本文法編〜

Java Basic 総復習

今まで、Javaを学習してきて、なんとなくはわかったけどクラスとかオブジェクトという言葉が出てきたら頭がこんがらがってきた。という事象があるかと思います。

<プログラミングのチュートリアル(説明)動画>

自分も昔そうでした。。。そうだったような気がします。

それならば、整理すれば良いのです。簡単な話です。

復習内容リスト

  1. プログラムの流れ
  2. 変数の扱い
  3. 式と演算子
  4. if文
  5. switch文
  6. while文
  7. for文

プログラムの流れ

まずは、プログラムの流れについて復習します。クラスやメソッドなどが出てきて処理があちこちに飛ぶように感じられると思いますが、そんなことはありません。順序立てて動いています。

まずは、メインメソッドが動く

どのクラスにも作成することができますが、1つのアプリケーションとして動かすときは、「必ずメインメソッドが動く」ということを忘れないでください。

例えば、下のようなコードがあったとします。

public class First {
 public static void main(String[] args) {
       System.out.println("Hello World");
       First main = new First();
       main.hello();
   }
   public void hello() {
       System.out.println("Second Hello World");
   }
}

この時に、メインメソッドの中では、クラスをnewしてやらないとメンバメソッド(インスタンスメソッド)は起動できません。
それは、「static」がついているメソッドは、特別なメソッドなので、インスタンスメソッドと区別されます。

ここでの、処理の順番は、以下のようになります。

  1. メインメソッドが動く
  2. 「Hello World」をコンソールに出力
  3. Firstクラスをインスタンス化
  4. インスタンスメソッドの「hello()」を呼び出す

このように動きます。ここでの注意ポイントは「First」クラス型の変数「main」です。

変数の扱い

変数はプログラムを動かすために必要になるものですが、あまり細かいところまで解説をすることが少ないです。
実際に、覚えることはint型は「整数」とか、「double」型は少数。。。
というように、データ型の用途に対する説明のみになってしまうからです。

変数には「プリミティブ型」と「参照型(クラス型)」がありますが、参照型に関しては自作クラスも参照型として分類されるので
プリミティブ型のように「これは整数型です」というような言い方ができません。

ただし、String型はクラス型です。他にも、int型を参照型にしたものがあります。それぞれ下のようになっています。
<プリミティブ型 -> 参照型>

  • int -> Integerクラス
  • double -> Doubleクラス
  • boolean -> Booleanクラス
  • long -> Longクラス
  • float -> Floatクラス

<リテラルに関する解説>

変数の定義方法は全て同じ

今までよく目にしている、下のような変数の宣言は理解できていると思います。

int num = 0;
String str = "はじめの一歩";

変数の宣言・初期化は必ず「データ型 変数名 = 代入する値」という形で行います。

これは変数のデータ型がどんなものになっても変わりません。

<変数の扱い方>

データ型とは

以下のものがあります。

  1. int, double, float, lognなどのプリミティブ型と呼ばれる(分類される)変数の型
  2. String, 配列(int[], double[], String[], クラス名[])などの参照型と呼ばれる(分類される)変数の型

例. 変数宣言(初期化)

int num = 0;
String str = "はじめの一歩";
First main = new  FIrst();
List<String> list = new ArrayList<String>();
Scanner scan = new Scanner(System.in);
Random rnd = new Random();

上から順に

  1. int型の変数numを0で初期化
  2. 文字列型(String型)の変数strを"はじめの一歩”で初期化
  3. First型の変数mainをFirstクラスのインスタンスを生成して初期化
  4. List\<String>型の変数listをArrayList\<String>クラスをインスタンス化して代入
  5. Scanner型の変数scanにScannerクラスをインスタンス化して代入
  6. Random型の変数rndにRandomクラスをインスタンス化して代入

式と演算子

演算子には以下のようなものがあります。
算術演算子:「+」 「-」 「*」 「/」 「%」 「^」 「++」 「--」
比較演算子:「==」 「!=」 「「<」 「>」 「<=」 「>=」
論理演算子:「&&」 「||」

そのほかの演算子
instanceof」:クラス型の比較を行います。

String st = "aa";
if (st instanceof String) {
    System.out.println("同じString型です。");
}

代入演算子:「=」値を代入します。

int num = 0; // int型の変数に0を代入
First first = new First(); // First型の変数firstにFirstクラスのインスタンスを代入
String st = "aaa"; // String型の変数stに文字列「aaa」を代入

ここで注意して欲しいのが、「1」と「"」がついていないもの、リテラル(値)は「数値」として扱われる
逆に「"」で囲われているもの、リテラル(値)は文字列としてある変われる

この「=」が、いまいち、ピンとこない人に向けて例を以下に書きます。

public static void main(String[] args) {
    String st = getString();
}
public static String getString() {
     return "String";
}

上のコードは、クラスを省略して書いていますが、メインメソッドから「getString()」というメソッドを呼び出します。
この「getString()」は返り値(戻り値)にString型(文字列型)を定義しています。

なので、「getString()」のメソッドを呼び出したらString型の値を受け取ることができます。

これに対して、クラスをnewして実行した時に関しても同じです。ちょっと長いですが。。。

public class Sample {
    /** フィールド変数 */
    private int field_int = 0;
    private String field_String = "もじれつ";
    //////// 注意(教科書の書き方はほぼ使わない) /////
    // String package_String = "使わない";

    public static void main(String[] args) {
        // Sampleクラス型の変数mainにSampleクラスをインスタンス化して代入
        Sample main = new Sample();
        // 返り値(戻り値)が「void」の場合は変数を受け取る必要がない
        main.hello();
        staticHello();

        // 返り値(戻り値)が定義されている場合(voidになっていない場合)
        // 返り値(戻り値)を受け取ることができる
        Sring result = getString();
        System.out.println("getString()の戻り値は" + result);
    }

    public static void staticHello() {
        System.out.println("Hello World");
    }
    /**
     * <コンストラクタの書き方>
     * アクセス修飾子 クラス名(引数) { ... }
     *
     * newした時の処理を書く
     */
    public Sample() {
        this.field_int = 5;
        this.field_String = "aaaa時の値";
    }

    /**
     * コンストラクタのオーバーロード
     * @param num
     * @param str
     */
    public Sample(int num, String str) {
        this.field_int = num;
        this.field_String = str;
    }

    /**
     * ハローメソッド
     */
    public void hello() {
        System.out.println(this.field_String);
        this.hello("こんにちは、フィールド変数:" + this.field_int);
        this.hello2();
    }
    /**
     * ハローメソッド
     */
    public void hello2() {
        System.out.println(this.field_String);
        this.hello("こんにちは、フィールド変数:" + this.field_int);
        String st = "aa";
        String gg = "ss";
        if (st instanceof String) {
            System.out.println("同じString型です。");
        }
    }

    public String getString() {
        return "String";
    }
}

上記のコードのうち戻り値が「void」のものは以下になります。

  • helllo()
  • hello2()
  • staticHello()

そして。返却値(戻り値)の指定があるもの(voidではないもの)は以下の通りです。

  • getString()

このgetString()メソッドはString型の値を返しますので、呼び出し元(メインメソッド)ではString型の変数resultで受け取っています。
当然受け取らなくても良いので、下のように書いてもエラーは出ません。

getString();

上記の場合は、String型の値を受け取っても、変数に代入していないのでメインメソッドでは使用することができません。
使用する必要がなければ、このようなメソッドの呼び出しもOKです。

if文

条件分岐処理の構文です。

if (論理式) {
   // trueの場合の処理
} else {
  // falseの場合の処理
}

実際に使用するときは下のように書く

String st = "aa";
if (st instanceof String) {
    System.out.println("同じString型です。");
}
if ("aa".equals(st)) {
    System.out.println("stはaaです。");
} else if ("bb".equals(st) ) {
    System.out.println("stはbbです。");
} else {
    System.out.println("stはその他の値です。");
}

それぞれif (論理式) { ... }の「論理式」の部分で値が「true / false」が帰ってきたところで処理の流れが変わります。

論理式

返り値としてbooleanが返される式のことです。以下の指揮がそれにあたります。

boolean isTrue = "aaa".equals("aaa");
boolean isFalse = "aAb".equals("aaa");
isTrue = 1 == 1;
isFalse = 2 == 1;
isTrue = 1 < 2;
isFalse = 1 != 2;

「返る」というのは「=」の反対側に値を渡すという意味です。

switch文

上記のif文と同じ処理がかけます。下のようになります。

switch(st) {
case "aa": 
    System.out.println("stはaaです。");
    break;
case "bb":
    System.out.println("stはbbです。");
    break;
default:
    System.out.println("stはその他の値です。");
}

while文

繰り返し処理の最もシンプルなものです。
下のように論理式の結果が「true」の間繰り返し処理を行います。

int num = 0;
while (num < 10) {
     System.out.println("num = " + num);
     num++;
}

上のコードは「num = 0」〜「num = 9」までを表示します。

for文

繰り返し処理の最もおポピュラーなものです。

for (int i = 0; i < 10; i++) {
     System.out.println("num = " + num);
}

上のコードは「num = 0」〜「num = 9」までを表示します。

大まかに基本文法と変数の扱い方などを記載しました。

Java H2DB〜インストールからテストテーブル作成と表示〜

H2 データベースのインストール

ダウンロード先
上記のリンクから、下のようなページに遷移できます。

H2DBのダウンロード

そして、赤枠の部分をクリックします。

同様に、赤枠の部分をクリックします。

そうすると、「h2-XXXX-XX-XX.zip」のような名前のファイルがダウンロードできます。
サンプル:「h2-2019-10-14.zip」

h2DBのJARファイルをビルドパスに通す

Eclipseを開きプロパティ -> ライブラリ・タブを開きます

そして、赤枠にある「外部JARファイルの追加」をクリックします。
そこに、h2*.jarというファイルがあるのでそれを追加します。

bat(sh)ファイルを起動する

h2*.jarファイルの隣にある「h2.bat(Windows用)かh2.sh(Mac, Linux用)」のファイルを起動する(ダブルクリック)

http://localhost:8082」にアクセスするとしたのような画面が見れます

日本語の表示もできました。そしたら「~/test」と書いてある部分を自分の指定したパスに変更します。現状では、マイドキュメント直下です。

次のようなパスを入力しました。

jdbc:h2:/Users/ユーザー名/Java/jars/h2/db_file

そして「接続」ボタンをクリック少し待つとしたのような画面が見れます。

これで、DBの作成が完了です。

テーブルを作成する

テスト用のテーブルを作成します。
画面にある「SQLステートメントのサンプル」の下の部分をクリックします。

するとSQLが生成されて下のような表示に変わります。

そして、をクリックしますとテストテーブルが作成できます。

実行結果は下のようなものです。

JDBCで接続してみる

Javaプログラムをしたのように作成します。

  1. H2Dao.java

    public class H2Dao {
    private final String DB_URI = "jdbc:h2:/Users/takk/Java/jars/h2/db_file/test.mv.db";
    private Connection con;
    
    public H2Dao() throws SQLException {
        try {
            // DriverManager.getConnection(URI   , ユーザー名, パスワード(なし))
            con = DriverManager.getConnection(DB_URI, "sa", "");
            Statement stmt = con.createStatement();
            createTables(stmt);
            ResultSet result = stmt.executeQuery("select * from test;");
    
            while(result.next()) {
                int id = result.getInt(1);
                String name = result.getString(2);
                System.out.println("ID: " + id + " Name: " + name);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw e;
        }
    }
    
    public void createTables(Statement stmt) throws SQLException {
        String sql = "DROP TABLE IF EXISTS TEST;\n" + 
                "CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255));\n" + 
                "INSERT INTO TEST VALUES(1, 'Hello');\n" + 
                "INSERT INTO TEST VALUES(2, 'World');\n" + 
                "SELECT * FROM TEST ORDER BY ID;\n" + 
                "UPDATE TEST SET NAME='Hi' WHERE ID=1;\n" + 
                "DELETE FROM TEST WHERE ID=2;";
        stmt.execute(sql);
    }
    public void finalize() {
        try {
            con.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            con = null;
        }
    
    }
    }

そして、このクラスを動かします。今回は、JUnitを使用します。

public class H2DaoTest {

    @Test
    public void testConstractor() {
        try {
            H2Dao dao = new H2Dao();
        } catch (SQLException e) {
            fail("エラーになりました");
        }

    }
}

これで、実行した結果が緑になればOKです。

練習

ここまできたら、上記のコードpublic void createTables(Statement stmt) throws SQLException にあるSQLを改造してSQLを実行してみましょう。

ヒント

更新系の処理と検索(データの取得)系の処理では、呼び出すメソッドが違います。

  • 更新系:Statement#execute()
  • 検索系:Statement#executeQuery()

<更新系>

    private void execute(String sql) {
        try {
            Statement stmt = con.createStatement();
            stmt.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

<検索系>

    private List<String> executeQuery(String sql, boolean isRetuen) {
        System.out.println("*** executeQuery ***");
        List<String> list = new ArrayList<String>();
        try {
            Statement stmt = con.createStatement();
            ResultSet result = stmt.executeQuery(sql);
            ResultSetMetaData meta = result.getMetaData();
            int colCount = meta.getColumnCount();
            while(result.next()) {
                for (int i = 1; i <= colCount; i++) {
                    System.out.print(i + ": " + result.getString(i) + " ");
                }
                System.out.println();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (isRetuen) {
            return list;
        }
        return null;
    }

でわでわ。。。

Java を支えるクラスたちに目を向ける 〜Java API〜

イントロダクション

今まで、Javaを学習してきて、何気なく使用していたクラスがあります。

気づかいない間に使用しているものもあります。これらはjava.langパッケージに入っているクラス群で、importしなくても使用することができます。

その代表的なクラス(Java API)がStringクラス(文字列)です。

Java を支えるクラスたち

Java APIというとJava言語自体のことを指すのですが、解釈のしかたは人によって違うようです。

しかし、はっきりしているのは「Java言語で使用するクラス群のこと」だということです。

Stringクラスを使う

まずは、プログラムをガンガン実行するための準備をします。

<==プロジェクトの作成とJUnitの設定==>

そうすると、JUnitが使用できるようになります。

==JUnitを使った動画(再生リスト)==

<ミッション1>
以下のクラスを作成して、実行した結果が想定通りになることを確認してください。

手順

  1. 以下の「作成するパッケージ」を作成する
  2. 同様に「作成するクラス」を作成する
  3. 同様に「A. テストケースの作成」を作成する
  4. 同様に「B. 作成するクラスのフィールド」を作成する
  5. 同様に「C. 作成するメソッド」を作成する

== 作成するパッケージ ==
practice.自分の名前.util

==作成するクラス==
srcフォルダに、StringUtilsクラスを作成
testフォルダに、StringUtilsTestクラスを作成

==A. テストケースの作成==
以下の処理を確認するテストケースを作成します。

⑴ 2つの引数がどちらも空(から)文字("")、もしくは null の場合、定数EMPTY「0」を返す(retunする)
⑵ 2つの引数が等しい場合、定数EQUAL「1」を返す(returnする)
⑶ 2つの引数が、大文字小文字の区別をしないで、等しい場合、定数IGNORE「2」を返す(returnする)

<テストケース(メソッド)の書き方>

@Test
public void testStringUtils01() {
    StringUtils target = new StringUtils();
    // 作成するメソッドの<処理>の1の内容を確認する処理
    // assertEquals(想定する結果の値, 検証する値);
   assertEquals(StringUtils.EMPTY,  target.stringTest01("", null));
}

*上の例に習い、2、3の処理を確認する処理を作成しましょう。

==B. 作成するクラスのフィールド==

  1. 定数EMPTYを整数型「0」で初期化
  2. 定数EQUALを整数型「1」で初期化
  3. 定数IGNOREを整数型「2」で初期化

==C. 作成するメソッド==

  1. 戻り値(返り値): 整数型(int型)
  2. メソッド名: stringTest1
  3. 引数リスト: 文字列型 leftStr, 文字列型 rightStr
  4. 処理内容:

 <処理>
 a. 引数にある文字列が空("")であれば、定数EMPTYを返す
 b. 引数にある文字列 leftStrとrightStrが等しいのであれば、定数 EQUALを返す
 c. 引数にある文字列が leftStrとrightStrがであれば、定数IGNOREを返す

<ミッション2>
ミッション1で作成した、StringUtilsTestクラスに、以下のテストケースを追加
・「引数に渡した文字列を大文字に変換することを確認する」
・「引数に渡した文字列を小文字に変換することを確認する」

以下、手順に従いテストケースの作成及び、クラスの作成を行う

手順

*String#toUpperCase()の実装

  1. StringUtilsクラスのconvertUpper()メソッドの引数に、
      文字列「"aaa"」を渡し、結果が「"AAA"」と等しいことを確認する

*String#toLowerCase()の実装

  1. StringUtilsクラスのconvertLower()メソッドの引数に、
      文字列「"TeStA"」を渡し、結果が「"testa"」と等しいことを確認する

*String#startWith()とendWithの実装

  1. StringUtilsクラスのstartEndWith()メソッドの引数に、
      文字列「"starts"」を渡し、結果が「true」と等しいことを確認する
  2. StringUtilsクラスのstartEndWith()メソッドの引数に、
      文字列「"start"」を渡し、結果が「false」と等しいことを確認する5. StringUtilsクラスのstartEndWith()メソッドの引数に、
      文字列「"atarts"」を渡し、結果が「false」と等しいことを確認する
  3. StringUtilsクラスのstartEndWith()メソッドの引数に、
      文字列「"strings"」を渡し、結果が「true」と等しいことを確認する

*String#IndexOf()の実装

  1. StringUtilsクラスのfindStr()メソッドの引数に、
      文字列「"Tesea"」と「"e"」を渡し、結果が「1」と等しいことを確認する
  2. StringUtilsクラスのfindStr()メソッドの引数に、
      文字列「"Tesea"」と「"T"」を渡し、結果が「0」と等しいことを確認する

*String#lastIndexOf()の実装

  1. StringUtilsクラスのfindLastStr()メソッドの引数に、
      文字列「"Takashimaya"」と「"a"」を渡し、結果が「1」と等しいことを確認する
  2. StringUtilsクラスのfindLastStr()メソッドの引数に、
      文字列「"Tesea"」と「"e"」を渡し、結果が「3」と等しいことを確認する
    11 StringUtilsクラスのfindLastStr()メソッドの引数に、
      文字列「"Takashimaya"」と「"a"」を渡し、結果が「10」と等しいことを確認する

*String#substring()の実装
12 StringUtilsクラスのsubString()メソッドの引数に、
  文字列「"abcdefg"」、整数「0」、整数「3」を渡し、結果が「abc」と等しいことを確認する
13 StringUtilsクラスのsubString()メソッドの引数に、
  文字列「"abcdefg"」、整数「3」を渡し、結果が「efg」と等しいことを確認する
14 StringUtilsクラスのsubString()メソッドの引数に、
  文字列「"abcdefg"」、整数「3」、整数「7」を渡し、結果が「defg」と等しいことを確認する

*String#trim()の実装(スペースが入っているので注意しましょう)
15 StringUtilsクラスのtrimStr()メソッドの引数に、
  文字列「" abcd "」を渡し、結果が「abcd」と等しいことを確認する
16 StringUtilsクラスのtrimStr()メソッドの引数に、
  文字列「" a bcd "」を渡し、結果が「a bcd」と等しいことを確認する

*String#replace()の実装
17 StringUtilsクラスのreplaceStr()メソッドの引数に、
  文字列「"abcd"」、文字列「”c"」、文字列「"あ"」を渡し、結果が「abあd」と等しいことを確認する
18 StringUtilsクラスのreplaceStr()メソッドの引数に、
  文字列「"abcda"」、文字列「”a"」、文字列「"C"」を渡し、結果が「abCd」と等しいことを確認する

*String#replaceAll()の実装
19 StringUtilsクラスのreplaceStr()メソッドの引数に、
  文字列「"abcda"」、文字列「”c"」、文字列「"あ"」を渡し、結果が「abあd」と等しいことを確認する
20 StringUtilsクラスのreplaceStr()メソッドの引数に、
  文字列「"abcda"」、文字列「”a"」、文字列「"あ"」を渡し、結果が「あbcdあ」と等しいことを確認する

解答例

<StringUtils.java>

public class StringUtils {
    /** 定数 */
    public static final int EMPTY = 0;
    public static final int EQUAL = 1;
    public static final int IGNORE = 2;
    public static final int ERROR = -1;

    public int stringTest01(String str1, String str2) {
        if ("".equals(str1)) {
            return EMPTY;
        }
        if ("".equals(str2)) {
            return EMPTY;
        }
        return ERROR;
    }

    public int stringUtils02(String str1, String str2) {
        int result = ERROR;
//      if (this.isEmpty(str1, str2)) {
//          return ERROR;
//      }
        if (str1.equals(str2)) {
            result = EQUAL;
        } else {
            result = ERROR;
        }
        return result;
    }

    public boolean isEmpty(String str1, String str2) {
        if (str1 == null || str2 == null) {
            return true;
        }
        if ("".equals(str1) || "".equals(str2)) {
            return true;
        }
        return false;
    }
}

< StringUtilsTest>

public class StringUtilsTest {
    @Test
    public void testStringUtils01() {
        StringUtils target = new StringUtils();
         // 作成するメソッドの<処理>の1の内容を確認する処理
        // assertEquals(想定する結果の値, 検証する値);
        assertEquals(StringUtils.EMPTY,  target.stringTest01("", null));
    }

    @Test
    public void testStringUtils02() {
        StringUtils target = new StringUtils();
        assertEquals(StringUtils.EQUAL, target.stringUtils02("aaa", "aaa"));
        assertEquals(StringUtils.ERROR, target.stringUtils02("aaa", "aab"));
        //assertEquals(StringUtils.ERROR, target.stringUtils02(null, "aab"));
        assertEquals(StringUtils.IGNORE, target.stringUtils02("aaa", "AAA"));
    }
}

クラスの扱い方の練習

問題

  1. プロジェクト「JavaExamTrain」を作成してください、すでにプロジェクトが存在する場合は何もしなくて良いです。
  2. 以下のパッケージを作成してください
    ・ practice.exam.mondai
    ・ practice.exam.mondai.logic
  3. 同様に、添付のファイルをダウンロードもしくはコピーしてソースフォルダ「resources」に「sample.csv」を作成してください、またresourcesフォルダにビルドパスを通してください。
  4. 以下のクラスを作成してください
    ・practice.exam.mondai.MondaiMain
    ・practice.exam.mondai.logic.ExamLogic
  5. ExamLogicクラスに、以下のような実装をしてください。
    ・返り値(戻り値):なし、メソッド名:printMessage、引数:なし
    ・String型の配列hako を文字列「50」「sy」「s_」「jo」「5f」「3d」「es」で初期化してください。
    ・int型の配列hintを数値「3」「1」「2」「4」「0」「5」「6」で初期化してください。
    ・拡張for文を使って、変数hintの値に対応する番号(添え字)の、変数hakoの文字列を標準出力に出力してください。
  6. ExamLogicクラスに、以下のようなコンストラクタを実装をしてください。
    ・引数なし
    ・String型のフィールド変数nameに文字列「タイガー」を代入する
    ・int型のフィールド変数ageに数値「19」を代入する
    ・ExamSwordクラス型のフィールド変数swordにExamSwordクラスのインスタンスを代入する
    ※ExamSwordクラスはMondaiLogicクラスと同じパッケージに作成する
  7. ExamLogicクラスに、以下のようなコンストラクタを実装をしてください。
    ・引数:文字列
    ・String型のフィールド変数nameに文字列引数の文字列を代入する
    ・int型のフィールド変数ageに数値「19」を代入する
    ・ExamSwordクラス型のフィールド変数swordにExamSwordクラスのインスタンスを代入する
    ※ExamSwordクラスはMondaiLogicクラスと同じパッケージに作成する
    ・次のような文字列を表示してください。「[name]」「[age]」はそれぞれフィールド変数を示すものとする
    「私の名前は[name]です。[age]才です。エモノは[ExamSword#name]です。」
    ※[ExamSword#name]はExamSwordクラスのフィールド変数nameを示すものとする。
  8. MondaiMainクラスに以下のような実装をしてください。
    ・ExamLogic型のフィールド変数logicを作成してください。
    ・コンストラクタでフィールド変数logicにExamLogicのインスタンスを代入してください。
    ・メインメソッドで、logicクラスのインスタンス・メソッド「printMessage」を呼び出してください。

Java 例外の処理方法 〜try catchの使い方とFile入出力〜

イントロダクション

前回は、ポリモーフィズムの実装を行いました。

これは、クラスの継承関係を作り、クラスの型をうまく変換して多様な使い方を行うというものでした。

例えば、下のような使い方をしました。

勇者率いるパーティを表現

public static void main(String[] args) {
        Character[] party = new Character[2];
        party[0] = new Hero("太郎");
        party[1] = new Wizard("二郎");

        System.out.println("こんにちは、良いパーティですね。");
        for (int i = 0; i < party.length; i++) {
            // ここの処理を変更する必要がある
            System.out.println(party[i].getName() + "さん");
        }
}

この実装は、下の図のように、クラスの継承関係作り、Hero, Wizardのクラスを1つのデータ型( クラス型)として使用しています。

Javaプログラムは「型安全」なので、データ型は厳密です。

しかし、このような形でクラスの継承関係を作ると、いろんな組み合わせが可能になります。

このような実装のことを「ポリモーフィズム」と言いました。

例外処理

何かと倦厭されがちな「例外処理」ですが、上のポリモーフィズムの実装は単純なので例外処理がなくても問題ありませんが、これに対して、複雑な組み合わせを行った時、例外処理がないととても不便なのです。

==エラーの種類==

  1. 文法エラー
  2. 実行時エラー
  3. 論理エラー(仮にこう呼ぶ):処理の結果が想定通りでない。

そして、上のようなエラーがあったときにそれぞれの例外を投げます。これは、プログラムの文法で「Throw」という文言を使用するためです。日本語では「投げる」です。

例えば、例外の処理は以下の系統に分けることができます。

  • Error: 通常のアプリケーションであればキャッチすべきではない重大な問題
  • Exception: 通常のアプリケーションでキャッチされる可能性のある状態、クラスExceptionと、そのサブクラスのうちでRuntimeExceptionのサブクラスでないものがすべて、チェック例外になります。
  • RuntimeException: Java仮想マシンの通常の処理でスローすることができる各種の例外のスーパー・クラスです。

エラーがどこで起きたか分からない

稀に、例外が出てもエラーメッセージを見ない人がいますが、ちゃんと見ましょう。「どこでエラーが出ているのか?」はこの例外処理の結果を見ればわかるはずです。

そのように作れば良いのです。

File入出力

例外処理の代表的なものは「ファイル入出力」です。このファイル操作の処理を実装するときに必ず「IOException」が出てきます。ただし、ラップしているような処理は見えてきませんが。。。

そんなわけで、File入出力の実装をして見ましょう。

<プロパティファイルを読み込む(全部)>

private void loadProperties(String fileName) {
    Properties prop = new Properties();
    try {
        Path path = Paths.get("resources", fileName);

        if (isDebug) System.out.println("Path: " + path.getParent().toString() + "\\" + fileName);

        BufferedReader buf = Files.newBufferedReader(path);
        prop.load(buf);
    } catch (IOException ie) {
        System.out.println(fileName + "の読み込み時にエラーがありました。");
        ie.printStackTrace();
        System.exit(-1);
    }
    if (isDebug) System.out.println("propLength: " + prop.size());

    prop.keySet().stream().forEach(key-> {
        // key = 実行クラスの番号
        String className = prop.getProperty(key.toString());
        try {
            Class<CommandIF> klass = (Class<CommandIF>) Class.forName(className);
            clsMap.put(key.toString(), klass);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    });

    if (clsMap.size() == 0) {
        System.out.println("プロパティファイルにクラスが登録されていません。");
        System.exit(-1);
    }
}

この処理で、プロパティファイルに書いてある、キーから完全クラス名を取得し、クラス・オブジェクトを取得、Mapインターフェースに登録しています。

細かく見ていきますので、ご安心ください

ファイルの読み込み

ファイルの読み込み処理の部分です。以下に抜粋します。

    Properties prop = new Properties();
    try {
        Path path = Paths.get("resources", fileName);

        if (isDebug) System.out.println("Path: " + path.getParent().toString() + "\\" + fileName);

        BufferedReader buf = Files.newBufferedReader(path);
        prop.load(buf);
    } catch (IOException ie) {
        System.out.println(fileName + "の読み込み時にエラーがありました。");
        ie.printStackTrace();
        System.exit(-1);
    }

この部分はfileNameに文字列で「ファイル名」が入っている想定です。

想定というのは、そのようにメソッドを使ってもらう前提ということです。

そして、上から順に、

Properties prop = new Properties();

ここで、プロパティクラスをインスタンス化しています。

Path path = Paths.get("resources", fileName);

この行では、resourceフォルダ内にある「fileName」のパスを取得しています。*ファイルがないときはnullが返ります。

下の処理はデバック用の処理です。取得したパスを文字列で表示しています。

if (isDebug) System.out.println("Path: " + path.getParent().toString() + "\\" + fileName);

そして、ファイルを読み込むためのクラスを取得(インスタンス化)します。

BufferedReader buf = Files.newBufferedReader(path);

最後に、Propetiesクラスで、取得したファイルリーダー(クラス)からプロパティファイルをロードします。

お気付きの方がいるかもしれませんが、ここで読み込もうとしているのは、プロパティファイルです。

ここまでが、処理の説明になります。

例が処理について

例外処理に関しては、try { ... } catch (例外クラス) { ... }で囲まれた、処理を書きます。

具体的には、このように書きます。

    try {
        Path path = Paths.get("resources", fileName);

        if (isDebug) System.out.println("Path: " + path.getParent().toString() + "\\" + fileName);

        BufferedReader buf = Files.newBufferedReader(path);
        prop.load(buf);
    } catch (IOException ie) {
        System.out.println(fileName + "の読み込み時にエラーがありました。");
        ie.printStackTrace();
        // プログラムの強制終了
        System.exit(-1);
    }

このように、ファイルを読み込もうとしたときに、例外が発生する可能性があるので、下のコードはThrows文が書かれています。
<使用している部分>

BufferedReader buf = Files.newBufferedReader(path);

<呼び出しているメソッドの定義>

BufferedReader java.nio.file.Files.newBufferedReader(Path path) throws IOException

なので、throwをキャッチする処理を書かなくてはなりません。

このように、例外が発生する可能性があるのであれば、「throws」文を使い例外が発生する可能性があることを呼び出した側のメソッドに通知する必要があります。

逆にメソッドの内部で揉み消してしまうならば、下のようにtry-catchで処理をしてしまえば良いのです。

    try {
        // 何かしらの処理
    } catch (IOException ie) {
        System.out.println("エラーがありました。");
        ie.printStackTrace();
        // プログラムの強制終了
        System.exit(-1);
    }

実際に作ってみる

まずは、サンプルコードを見てください。実行確認済みです。

public static void main(String[] args) {
    Path path = Paths.get("resources", "mains.properties");
    try {
        BufferedReader read = Files.newBufferedReader(path);
        String line = null;
        while((line = read.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException ie) {
        ie.printStackTrace();
        System.exit(-1);
    }
}

メインメソッドで、ファイル読み込みの処理を行ったものです。

<処理内容>

  1. resourceフォルダ(ビルドパスが通っている)にある「mains.properties」のパスを取得します。
  2. ファイル読み込みクラス、BufferedReaderを作成(インスタンス化)します。
  3. ファイルの内容を1行ずつ、読み込み、読み込み行がないならばnullが返ってくるので処理を終了します。
     ファイルの内容を標準出力に出力している

このような形で、例外処理を行いますが、これを別なkたちで使用することもあります。

チェック時の例外を投げる

<入力チェックの例外>
【前提】
・CheckerUtils#fixStr()は以下のように定義している

public static boolean fixStr(String str) throws Exception {
    if (str == null) {
        throw new Exception("strはnullにできません");
    }
    System.out.println(str);
}

<呼び出し元>

public static void main(String[] arg) {
    try {
        ChecherUtis.fixStr("aaaa");
    } catch (Exception e) {
        e.printStackTrace();
        Systme.exit(-1);
    }
}

このようにすると、例外に「strはnullにできません」と表示することができます。

さらに、Exceptionクラスを拡張して、下のように、自前の例外を作成することも可能です。

public class HeroExceptiion extends Exception {
    public HeroExceptiion(String message) {
        super(message);
    }
}

結局のところは、例外クラスの名前が変わるだけなのですが、この例外が出るところは決まってくるので。デバック時も問題になりません。

結構便利です。

今回はこんなところで。。。

でわでわ。。。

継承に関するページ一覧

  1. Java オブジェクト指向基礎 ~オブジェクト指向コンセプト~
  2. UMLの書き方(読み方)〜概要とクラス図〜
  3. Java クラスの継承を理解する
  4. クラスの継承〜アクセス修飾子〜
  5. クラスの継承関係を作る1
  6. クラスの継承関係を作る2

環境構築関連ページ一覧

設計関連ページ一覧

  1. 設計を始める〜1.アプリイメージ〜
  2. 設計を始める〜2.機能イメージ〜
  3. 設計を始める〜3.機能概要〜
  4. Java はじめて16 〜クラス設計から実装〜

PHP関連ページ

  1. WordPress プラグイン作成〜DBを使用する〜
  2. PHP PDO 〜MySQLにアクセスする〜
  3. PHP Ajax 〜DBに登録したデータを受信する〜
  4. Google Maps API PHP連携 〜マップ情報をDBに登録する〜
  5. PHP Image File 〜iPhoneやAndroidでの画像送受信の問題〜
  6. AngularJS Routing 〜PHPをWeb APIにする〜
  7. WordPress PHPカスタム〜根本的に見た目を変える〜
  8. WordPress PHPカスタム〜根本的に見た目を変える2〜
  9. Eclipse PHPプラグイン 〜ElipseでWordPress環境を構築〜
  10. WordPress テスト実装 〜heade-test.phpを表示〜
  11. AngularJS + PHP 〜WordPressと連携する〜
  12. AngularJS + PHP 〜AngularJSの実装〜
  13. AngularJS + PHP 〜AngularJSの実装2〜
  14. WordPress 処理解析 ~index.phpを眺める~
  15. WordPress Plugin NewStatPress ~アクセス解析プラグインAPIを使う~
  16. WordPress 処理解析 ~ログイン処理を調べる~
  17. WordPressカスタム〜アンケートボタンを追加する(設計)〜
  18. WordPressカスタム〜プラグインの作成〜
  19. WordPressカスタム〜ダッシュボードのプラグイン画面作成〜
  20. WordPressカスタム〜ダッシュボードのプラグイン画面作成2〜
  21. WordPressカスタム〜ダッシュボードのプラグイン画面作成3〜
  22. WordPress プラグイン作成〜アンケート作成プラグインを作る〜

JS関連ページ

  1. JS GoogleMaps API 〜オリジナル・データマップを作ろう〜
  2. 吹き出しにYoubetubeを埋め込む
  3. Ajax + XmlHttpRequest〜画像送信からDB登録して表示〜
  4. JS XmlHttpRequest 〜JSでの同期/非同期通信〜
  5. JS Google Maps API 〜GeoLocation 現在位置の取得〜
  6. AngularJS + PHP 〜AngularJSの実装〜
  7. AngularJS + PHP 〜AngularJSの実装2〜
  8. WordPress プラグイン作成 〜$wpdbでのSELECT〜
  9. WordPressプラグイン作成 〜HTML挿入まで完了〜
  10. WordPress プラグイン作成 〜アンケート挿入〜
  11. MAMP 起動設定 〜WordPressのテスト環境を作る〜
  12. MAMP WordPress 〜インポート時のエラー対処〜
  13. WordPress PHPカスタム〜根本的に見た目を変える2〜

数理モデル関連ページ

  1. 数学への挑戦 第二弾〜数理モデルxプログラミング〜
  2. 数学への挑戦 第二弾〜実装編:数理モデルxプログラミング〜
  3. 数学への挑戦 第二弾〜集合を使う:数理モデルxプログラミング〜
  4. 数学への挑戦 第二弾〜確率変数:数理モデルxプログラミング〜
  5. 数学への挑戦 第二弾〜期待値と分散:数理モデルxプログラミング〜
  6. 数学への挑戦 第二弾〜卒業までに彼氏ができる確率:数理モデルxプログラミング〜
  7. 数学への挑戦 第二弾〜確率変数の足し算:数理モデルxプログラミング〜
  8. 数学への挑戦 第二弾〜まとめ1:数理モデルxプログラミング〜

Java ポリモーフィズム(多様性) 〜実装をしてみる〜

イントロダクション

前回の学習を踏まえて、抽象クラス、インターフェースを使用して簡単なプログラムを作成してみようと考えています。

頭で理解しても、実践が伴わなければものになりません

前回の学習ポイント

継承関係を作り、下の図のようなクラス関係を作成しました。

そして、RpgCharacterクラスは、抽象クラスです。

以下のような手順で作成しました。

!. 通常のlクラスを作成する(RpgCharacter)

  1. 必要なプロパティ(属性を追加する)
  2. それぞれのGeter&Setterを作成
  3. このクラスを継承するすべてのクラスに共通するであろうメソッドを作成
    /** にげる */
    public void escape() {
    System.out.println(this.name + "は逃げ出した");
    }
  4. 実装する各クラスによって別の処理をさせたいので、抽象メソッドを作成
    /** 抽象メソッド「たたかう」 */
    public void attack(Monster monst);
  5. RpgCharacterクラスを継承して、Wizardクラスなどのクラスを作成する

このように、クラス関係を作ると、RpgCharacterクラスを継承したクラスを全てRpgCharacterクラス型の変数で各クラスオブジェクトを使用することができる。
<RpgCharacterクラス型の変数でいろんなクラスを使う>

public static void main(String[] args) {
        RpgCharacter[] party = new RpgCharacter[2];
        party[0] = new RpgHero("太郎");
        party[1] = new RpgWizard("二郎");

        System.out.println("こんにちは、良いパーティですね。");
        for (int i = 0; i < party.length; i++) {
            System.out.println(party[i].getName() + "さん");
        }
    }

ポリモーフィズムの実装

前回学習したものを実装して、「動くもの」を作成しようというところです。

実装する手順を考える

実装するのには、それなりの時間がかかりますが、やってみることの意義はすごく大きいです。

今回は、キャラクターを作成する処理から実装していこうと考えています。

<作成するものVersion1>

  1. 勇者とモンスターが1回ずつ攻撃する
  2. それぞれの攻撃に対して、各キャラクターのHPを減算する

メインメソッドの実装

ここでは、プログラムをイチから作成する方向で、話を進めていきます。

作成したプログラムは下のような実行結果が得られるように、実装します。

まずは、プログラムを実行するためのクラス(BattleSample.java)を作成します。エラーが出る部分はコメントアウトします。

つまるところは、どのような処理を呼び出したいかを実装します。ちなみにコメントのみでも良いです。

バージョン1の実装

<BattleSample.java-バージョン1

public static void main(String[] args) {
    //勇者クラスの生成 
    RpgHero hero = new RpgHero("勇者");
    // モンスタークラスの生成
    Slime slime = new Slime("スライムA");

    // 勇者の攻撃
    hero.attack(slime);
    // モンスターの攻撃
    slime.attack(hero);
}

このように、勇者クラスと、スライムクラスをインスタンス化してそれぞれのメソッド(コマンド)を呼び出してやるだけのシンプルな実装です。

これで、勇者とスライムの攻防がコンソール(標準出力)へ出力されます。

問題は、RpgHeroクラスとSlimeクラスができていないという部分です(前回の実装を行った人は作成済みです)

RpgHeroクラスを作る

このクラスは、下の図にあるように、RpgCharacterクラスを継承した形で、実装します。

なので、先にRpgCharacterクラスを作成する必要がありますので、こちらのクラスの製造に着手します。

RpgCharacterクラスの製造

このクラスは、湯者だけではなく魔法使いや、盗賊、戦士などのプレーヤー側のキャラクターに共通する部分を実装する
想定で、設計しました。

なので、下のように共通するもの(属性・振る舞い)を実装します。

つまり、現状では、通常のクラスになります。

public class RpgCharacter {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;
    /** 性別 */
    protected int sex;
    /** 年齢 */
    protected int age;
    /** 誕生日 */
    protected String birthDay;
   ・
   ・
   ・
}

上の状態では、属性(フィールド変数)を定義した状態です。

このほかに追加したいものもあるので、一度内容を確認します。

<RpgCharacterクラスの設計1>

  1. 属性、名前を持っている
  2. 属性、MPを持っている
  3. 属性、年齢を持っている
  4. 属性、性別を持っている
  5. 属性、誕生日を持っている

個の状態では、共通するプロパティ(属性)のみが定義されています。ほかにも考えれば出てきそうですが。。。

そして、共通するコマンド(メソッド)を定義します。

<RpgCharacterクラスの設計2>

  1. 属性、名前を持っている
  2. 属性、MPを持っている
  3. 属性、年齢を持っている
  4. 属性、性別を持っている
  5. 属性、誕生日を持っている
  6. 振る舞い、にげるを持っている

作成した設計を元に、そのクラスを実装します。

<RpgCharacter>バージョン1

public class RpgCharacter {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;
    /** 性別 */
    protected int sex;
    /** 年齢 */
    protected int age;
    /** 誕生日 */
    protected String birthDay;

    /** にげる */
    public void escape() {
        System.out.println(this.name + "は逃げ出した");
    }

フィールド変数には、本来「private」修飾氏をつけるのですが、今回は、子クラスを作成するための親クラスとして作成しているので、「protected」をつけて、継承関係のあるクラスであれば参照可能な形にしています。

そして、Getter, Setterは省略していますので、それぞれのメソッドが実装されているていで話を進めます。

この状態では、「たたかう」メソッドを強制的に継承する子クラスに実装させることができないので、下のような、抽象メソッドを追加します。

    /** たたかう */
    public abstract void attack(RpgCharacter character);

このようにすると、「抽象メソッドは抽象クラス、インターフェースでないともていない」ので、RpgCharacterクラスを通常のクラスから「抽象クラス」に変更します。

public abstract class RpgCharacter {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;
    /** 攻撃力 */
    protected int attackPower;
    /** 防御力 */
    protected int diffencePower;
    /** 性別 */
    protected int sex;
    /** 年齢 */
    protected int age;
    /** 誕生日 */
    protected String birthDay;

    /** 使用できるコマンドのメニューを開く */
    public abstract void showMenu();
    /** たたかう */
    public abstract void attack(RpgCharacter character);
    /** にげる */
    public void escape() {
        System.out.println(this.name + "は逃げ出した");
    }

そして、このクラスをインスタンス化するとき(newするとき)にデフォルトの値を設定するための

コンストラクタを定義(実装)します。引数に名前だけを与えた場合「コンストラクタ1」と、引数にすべてのプロパティ(属性)を与えた場合「コンストラクタ2」を定義しました。

    /** コンストラクタ1 */
    public RpgCharacter(String name) {
        this.name = name;
        this.hp = 10;
        this.mp = 0;
    }

    /** コンストラクタ2 */
    public RpgCharacter(String name, int sex, int age, String birthDay) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.birthDay = birthDay;
    }

RpgHeroを作る

ここでRpgHeroクラスの製造に戻ります。

ここまできたら、シンプルにRpgCharacterクラスを継承したRpgHeroクラスを作成するだけです。抽象メソッドのオーバーライドがありますが。。。

public class RpgHero extends RpgCharacter {
    /** コンストラクタ */
    public RpgHero(String name) {
        super(name);
    }
    /** コンストラクタ */
    public RpgHero(String name, int sex, int age, String birthDay) {
        super(name, sex, age, birthDay);
    }

    @Override
    public void attack(RpgCharacter monst) {
        System.out.println(this.name + "の攻撃");
        int damage = getAttackPower() - monst.getDiffencePower();
        System.out.println(monst.getName() + "へ" + damage + "のダメージ");
        monst.setHp(monst.getHp() - damage);
    }
}

継承したクラス(子クラス)から親クラスのコンストラクタ、メソッド、フィールドを呼び出したい場合は「super」をつけてやります。

同様に自分のクラス(子クラス)で保持するもの(コンストラクタ、メソッド、フィールド)を呼び出したい場合は「this」をつけてやります。

そして「@Override」というアノテーションがついているメソッドは、抽象メソッドを「オーバーライド」していることを明示的に示しています。

これと同様に、MonsterクラスとSlimeクラスも作成してしまいましょう。

Monsterクラスの製造

public class Monster extends RpgCharacter {

    /**
     * @param name
     */
    public Monster(String name) {
        super(name);
    }

    @Override
    public void attack(RpgCharacter player) {
        System.out.println(this.name + "の攻撃");
        int damage = getAttackPower() - player.getDiffencePower();
        System.out.println(player.getName() + "へ" + damage + "のダメージ");
        player.setHp(player.getHp() - damage);
    }
}

必要な属性(フィールド)はRpgCharacterクラスで持っているので、このクラスに特有な部分のみを実装します。

そして、コンストラクタに関しては、細かい情報(性別、年齢など)は必要な時にsetAge()などのメソッドで設定すれば良いので明示できに書きません。

その代わり、RpgCharacterクラスの、初期値としては「不明」「-1」などの値を設定するようにします。

int型は、参照型のようなnullという値が使えないので、-1で代用します。

つまりは、「年齢が『-1』だった場合『年齢不詳』という意味にする」というルールを追加してやれば、この問題は解決出るのでそのようにしたというところです。

スライムクラス

public class Slime extends Monster {

    /**
     * @param name
     */
    public Slime(String name) {
        super(name);
    }
}

このクラスに至っては、コンストラクタのみの実装で事足ります。

<<<前回

継承に関するページ一覧

  1. Java オブジェクト指向基礎 ~オブジェクト指向コンセプト~
  2. UMLの書き方(読み方)〜概要とクラス図〜
  3. Java クラスの継承を理解する
  4. クラスの継承〜アクセス修飾子〜
  5. クラスの継承関係を作る1
  6. クラスの継承関係を作る2

環境構築関連ページ一覧

設計関連ページ一覧

  1. 設計を始める〜1.アプリイメージ〜
  2. 設計を始める〜2.機能イメージ〜
  3. 設計を始める〜3.機能概要〜
  4. Java はじめて16 〜クラス設計から実装〜

PHP関連ページ

  1. WordPress プラグイン作成〜DBを使用する〜
  2. PHP PDO 〜MySQLにアクセスする〜
  3. PHP Ajax 〜DBに登録したデータを受信する〜
  4. Google Maps API PHP連携 〜マップ情報をDBに登録する〜
  5. PHP Image File 〜iPhoneやAndroidでの画像送受信の問題〜
  6. AngularJS Routing 〜PHPをWeb APIにする〜
  7. WordPress PHPカスタム〜根本的に見た目を変える〜
  8. WordPress PHPカスタム〜根本的に見た目を変える2〜
  9. Eclipse PHPプラグイン 〜ElipseでWordPress環境を構築〜
  10. WordPress テスト実装 〜heade-test.phpを表示〜
  11. AngularJS + PHP 〜WordPressと連携する〜
  12. AngularJS + PHP 〜AngularJSの実装〜
  13. AngularJS + PHP 〜AngularJSの実装2〜
  14. WordPress 処理解析 ~index.phpを眺める~
  15. WordPress Plugin NewStatPress ~アクセス解析プラグインAPIを使う~
  16. WordPress 処理解析 ~ログイン処理を調べる~
  17. WordPressカスタム〜アンケートボタンを追加する(設計)〜
  18. WordPressカスタム〜プラグインの作成〜
  19. WordPressカスタム〜ダッシュボードのプラグイン画面作成〜
  20. WordPressカスタム〜ダッシュボードのプラグイン画面作成2〜
  21. WordPressカスタム〜ダッシュボードのプラグイン画面作成3〜
  22. WordPress プラグイン作成〜アンケート作成プラグインを作る〜

JS関連ページ

  1. JS GoogleMaps API 〜オリジナル・データマップを作ろう〜
  2. 吹き出しにYoubetubeを埋め込む
  3. Ajax + XmlHttpRequest〜画像送信からDB登録して表示〜
  4. JS XmlHttpRequest 〜JSでの同期/非同期通信〜
  5. JS Google Maps API 〜GeoLocation 現在位置の取得〜
  6. AngularJS + PHP 〜AngularJSの実装〜
  7. AngularJS + PHP 〜AngularJSの実装2〜
  8. WordPress プラグイン作成 〜$wpdbでのSELECT〜
  9. WordPressプラグイン作成 〜HTML挿入まで完了〜
  10. WordPress プラグイン作成 〜アンケート挿入〜
  11. MAMP 起動設定 〜WordPressのテスト環境を作る〜
  12. MAMP WordPress 〜インポート時のエラー対処〜
  13. WordPress PHPカスタム〜根本的に見た目を変える2〜

数理モデル関連ページ

  1. 数学への挑戦 第二弾〜数理モデルxプログラミング〜
  2. 数学への挑戦 第二弾〜実装編:数理モデルxプログラミング〜
  3. 数学への挑戦 第二弾〜集合を使う:数理モデルxプログラミング〜
  4. 数学への挑戦 第二弾〜確率変数:数理モデルxプログラミング〜
  5. 数学への挑戦 第二弾〜期待値と分散:数理モデルxプログラミング〜
  6. 数学への挑戦 第二弾〜卒業までに彼氏ができる確率:数理モデルxプログラミング〜
  7. 数学への挑戦 第二弾〜確率変数の足し算:数理モデルxプログラミング〜
  8. 数学への挑戦 第二弾〜まとめ1:数理モデルxプログラミング〜

Java ポリモーフィズム(多様性) 〜クラス型の変換と組み合わせ〜

インロトダクション

前回は抽象クラスとインターフェースについて学習しました。

今回は、以下の3つを組み合わせて、どのような仕組みを作ることができるのか?について学習したいと思います。

はっきり言って、「どのような仕組みを作ることができるのか?」の問いに対する答えは、「ほぼ無限の組み合わせ方、仕組みを作ることができる」と思います。という答えが言えます。

前回までに、クラスとクラスを組み合わせるための土台になる部分を学習しました。以下のような内容です。

  • クラスの継承関係を作成する(親クラスと子クラス)
  • 抽象クラスとインターフェース

これらの仕組み(継承関係を作る)を使用して、どのような組み合わせ方ができるのか学習していきます。
世間巷には「デザインパターン」という名前で広く知られています。が、デザインパターンなどのように広く知られるものは
大体Java APIの方で実装してあるので、使い方さえ分かっていれば改めて実装する必要はありません。

ポイントになるのは、「クラス関係を作成して、どのような仕組みを実現するか?」というところです。

ポリモーフィズムの実装

「テキストRPGを作る」ということをテーマ(話題)として話を進めていきます。

前回までに作成したもの

親クラス、子クラス。。。として以下のようなクラスを作成したいと考えています。下のようなクラスたちです。

具体例A
テキストRPGゲームを作成しようとしているので下のようなクラスを作成したいと思っている。

  1. 勇者・クラス <作成済み>
  2. 魔法使い・クラス <作成済み>
    3.盗賊・クラス
  3. 超勇者クラス
  4. マタンゴ・クラス
  5. ポインズンマタンゴ・クラス
  6. ゴブリン・クラス
  7. ウェアウルフ・クラス
  8. デスバット・クラス

そして、プレーヤー側のクラスの親になるCharacterクラスも作成しました。(詳細は前回を参照ください。)

ポリモーフィズムの設計

先ずは、設計から入ります。

組み合わせて、プログラムを実行するのに「どう組み合わせるか?」を考えないと始まらないのです。

自分の場合は、まずは紙と鉛筆を持ってプログラミングを始めます。つまり「設計から始める」ということです。

RPGのパーティを考える

例えば、前回作成したCharacterクラスとは別に「RpgCharacter」というクラスを作成します。
このクラスは、下の図のように勇者クラス(RpgHero)や魔法使いクラスを作成したとします。

そうすると、下のようなコードが書けます。(エラーが出ません)

<メインメソッド>

    public static void main(String[] args) {
        RpgCharacter[] party = new RpgCharacter[2];
        party[0] = new RpgHero("太郎");
        party[1] = new RpgWizard("二郎");

        System.out.println("こんにちは、良いパーティですね。");
        for (int i = 0; i < party.length; i++) {
            System.out.println(party[i].getName() + "さん");
        }
    }

このように、RpgCharacterクラスを継承しているクラスなので、RpgCharacterの配列をパーティとして扱うことができます。

そして、MonsterもRpgCharacterを継承することになるので、モンスターも仲間(パーティ)に追加できます。

RpgCharacterに処理をまとめる

現状では、勇者や魔法使い、モンスターなどの使用できるコマンドは「たたかう」というコマンドのみです。

ここに、すべてのキャラクターに共通する「にげる」コマンドを追加します。
それには、下のようにコードを追加します。

<RpgCharacterクラスの修正>

public abstract class RpgCharacter {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;

    /** にげる */
    public void escape() {
        System.out.println(this.name + "は逃げ出した");
    }
}

この状態で、RpgCharacterクラスを継承するクラスは「にげる」コマンドを使用することができます。

しかし「全く同じではない処理を追加する場合」はどうでしょうか?

例えば、「たたかう」コマンドの場合です。勇者クラスと魔法使いクラスでは、攻撃力が違うはずです。

この場合は、与えるダメージの大きさをそのクラスによって変えられるようにする必要があります。

その仕組みとして「抽象メソッド」を使用する方法があります。

具体的には下のようなコードです。

<抽象メソッドを追加する>

    /** たたかう */
    public abstract void attack(RpgCharacter character);

実装したクラスのコードは下のようになります。

<抽象メソッドを追加したクラス>

public abstract class RpgCharacter {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;

/** たたかう */
    public abstract void attack(RpgCharacter character);
    /** にげる */
    public void escape() {
        System.out.println(this.name + "は逃げ出した");
    }

そして、これらのクラスを生成するとき(newするとき) には、コンストラクタが必要になりますが、これもRpgCharacterクラスと同じものになりますので、下のようにコンストラクタを追加します。

<コンストラクタを追加したクラス>

public abstract class RpgCharacter {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;

    /** コンストラクタ */
    public RpgCharacter(String name) {
        this.name = name;
        this.hp = 10;
        this.mp = 0;
    }

/** たたかう */
    public abstract void attack(RpgCharacter character);
    /** にげる */
    public void escape() {
        System.out.println(this.name + "は逃げ出した");
    }

そうすると初めにも書きましたが、このようなコードでの処理が実行できます。

    public static void main(String[] args) {
        RpgCharacter[] party = new RpgCharacter[2];
        party[0] = new RpgHero("太郎");
        party[1] = new RpgWizard("二郎");

        System.out.println("こんにちは、良いパーティですね。");
        for (int i = 0; i < party.length; i++) {
            System.out.println(party[i].getName() + "さん");
        }
    }

実行結果は下のようになります。

こんにちは、良いパーティですね。
太郎さん
二郎さん

<<<前回 次回 >>>

継承に関するページ一覧

  1. Java オブジェクト指向基礎 ~オブジェクト指向コンセプト~
  2. UMLの書き方(読み方)〜概要とクラス図〜
  3. Java クラスの継承を理解する
  4. クラスの継承〜アクセス修飾子〜
  5. クラスの継承関係を作る1
  6. クラスの継承関係を作る2

環境構築関連ページ一覧

設計関連ページ一覧

  1. 設計を始める〜1.アプリイメージ〜
  2. 設計を始める〜2.機能イメージ〜
  3. 設計を始める〜3.機能概要〜
  4. Java はじめて16 〜クラス設計から実装〜

PHP関連ページ

  1. WordPress プラグイン作成〜DBを使用する〜
  2. PHP PDO 〜MySQLにアクセスする〜
  3. PHP Ajax 〜DBに登録したデータを受信する〜
  4. Google Maps API PHP連携 〜マップ情報をDBに登録する〜
  5. PHP Image File 〜iPhoneやAndroidでの画像送受信の問題〜
  6. AngularJS Routing 〜PHPをWeb APIにする〜
  7. WordPress PHPカスタム〜根本的に見た目を変える〜
  8. WordPress PHPカスタム〜根本的に見た目を変える2〜
  9. Eclipse PHPプラグイン 〜ElipseでWordPress環境を構築〜
  10. WordPress テスト実装 〜heade-test.phpを表示〜
  11. AngularJS + PHP 〜WordPressと連携する〜
  12. AngularJS + PHP 〜AngularJSの実装〜
  13. AngularJS + PHP 〜AngularJSの実装2〜
  14. WordPress 処理解析 ~index.phpを眺める~
  15. WordPress Plugin NewStatPress ~アクセス解析プラグインAPIを使う~
  16. WordPress 処理解析 ~ログイン処理を調べる~
  17. WordPressカスタム〜アンケートボタンを追加する(設計)〜
  18. WordPressカスタム〜プラグインの作成〜
  19. WordPressカスタム〜ダッシュボードのプラグイン画面作成〜
  20. WordPressカスタム〜ダッシュボードのプラグイン画面作成2〜
  21. WordPressカスタム〜ダッシュボードのプラグイン画面作成3〜
  22. WordPress プラグイン作成〜アンケート作成プラグインを作る〜

JS関連ページ

  1. JS GoogleMaps API 〜オリジナル・データマップを作ろう〜
  2. 吹き出しにYoubetubeを埋め込む
  3. Ajax + XmlHttpRequest〜画像送信からDB登録して表示〜
  4. JS XmlHttpRequest 〜JSでの同期/非同期通信〜
  5. JS Google Maps API 〜GeoLocation 現在位置の取得〜
  6. AngularJS + PHP 〜AngularJSの実装〜
  7. AngularJS + PHP 〜AngularJSの実装2〜
  8. WordPress プラグイン作成 〜$wpdbでのSELECT〜
  9. WordPressプラグイン作成 〜HTML挿入まで完了〜
  10. WordPress プラグイン作成 〜アンケート挿入〜
  11. MAMP 起動設定 〜WordPressのテスト環境を作る〜
  12. MAMP WordPress 〜インポート時のエラー対処〜
  13. WordPress PHPカスタム〜根本的に見た目を変える2〜

数理モデル関連ページ

  1. 数学への挑戦 第二弾〜数理モデルxプログラミング〜
  2. 数学への挑戦 第二弾〜実装編:数理モデルxプログラミング〜
  3. 数学への挑戦 第二弾〜集合を使う:数理モデルxプログラミング〜
  4. 数学への挑戦 第二弾〜確率変数:数理モデルxプログラミング〜
  5. 数学への挑戦 第二弾〜期待値と分散:数理モデルxプログラミング〜
  6. 数学への挑戦 第二弾〜卒業までに彼氏ができる確率:数理モデルxプログラミング〜
  7. 数学への挑戦 第二弾〜確率変数の足し算:数理モデルxプログラミング〜
  8. 数学への挑戦 第二弾〜まとめ1:数理モデルxプログラミング〜