2012年3月31日土曜日

【Java】オブジェクトの比較

前回は条件文と演算子について書きましたが、その中で値の比較を行っていました。
if (num == 0) { } // 変数宣言は省略
みたいなのです。
numと0が等しいかどうかを比較しています。

それでは文字列を扱うString型の比較はどうでしょうか?
String zero = "0";
if (zero == 0) { } // TRUEを返す
これはTRUEとなります。
では次のはどうでしょう?
String zero = "0";
String zeroNew = new String("0");
if (zero == zeroNew) { } // FALSEを返す
これはFALSEとなります。
参照型の場合はプリミティブ型の場合と異なり、
値そのものでなくオブジェクトの比較が行われます。
この場合、newされたzeroNewが指す"0"を格納したアドレスは
zeroのものとは違うアドレス(それこそ新しいアドレス)のため、FALSEとなります。

以前説明に使用したジョブクラスを使用して説明してみます。
シーフ siroco = new シーフ(); // シーフクラスのsirocoインスタンスを生成
シーフ kururu = new シーフ(); // シーフクラスのkururuインスタンスを生成

if (siroco == kururu ) { } // FALSEを返す
この方がわかりやすいんじゃないでしょうか?
同じシーフクラスのインスタンスでも、sirocoとkururuは別人ですもんね。

それではオブジェクトが指している"値"を比較するにはどうしたらいいでしょうか?
それはObjectクラスのメソッド、equalsを使用します。
String zero = "0";
String zeroNew = new String("0");
if (zero.equals(zeroNew)) { } // TRUEを返す
この例ではString型のzeroインスタンスのequalsメソッドを使用して、
 同じくString型のzeroNewインスタンスとの比較を行っています。
(参照型のクラスはすべてObjectクラスを継承しているため、equalsを使う事が出来る)
equalsなら別インスタンスでも値の比較ができ、求めている結果が得られます。

文字列の比較は結構やると思いますので、
くれぐれも"=="で比較しないように~

今回は以上です。
次回は繰り返し処理について書いていきます。

2012年3月24日土曜日

【Java】条件文と演算子

プログラムを組んでいる際、条件を与えて
その条件ごとで処理を変えたいことがあります。

例えば、
右の宝箱を開けると「ブレイブブレイド」がもらえる。
左の宝箱を開けると「チキンナイフ」がもらえる。
みたいな時です。
(やっぱりFF5。因みにsirocoはチキンナイフ派)

これをJavaで書くと次のような感じ。
if (右の宝箱を選択) {
 // ブレイブブレイドを入手
} else {
 // チキンナイフを入手
}
簡単な英語が分かれば理解できると思いますが、
if を使用して条件文を表すことができます。
if のあとの括弧内に条件をいれ、それが真の時に { } 内の処理を実行します。
else はif の条件を満たさない場合を意味し、else以降の { } 内の処理を実行します。

では次の条件をif 文で書いてみます。
『変数num が0ならば、変数str に"ぜろ"を代入し、num が1ならば、str に"いち"を代入し、それ以外なら、str に"それ以外"を代入』
int num = 0;
String str;

if (num == 0) {
 str = "ぜろ";
} else if (num == 1) {
 str = "いち";
} else {
 str = "それ以外";
}
else のあとに if を続けることで、条件を続けて書くことができます。
"=="は、その左の値と右の値が一致するという意味です。
(オブジェクトの場合は、左右のインスタンスが一致)

"=="など値の比較を行うものを、比較演算子と言います。
比較演算子には次の種類があります。

<小なり
<=小なりイコール
==イコール
>=大なりイコール
>大なり

『変数num が10より大きくて、且つ20より小さい場合は変数str に"あたり"を代入』
これをif 文で書くと、、、
int num = 12;
String str;

if (num > 10) {
 if (num < 20) {
  str = "あたり";
 }
}
条件を加えてみましょう。
『それ以外の場合は、strに"はずれ"を代入』
int num = 12;
String str;

if (num > 10) {
 if (num < 20) {
  str = "あたり";
 } else {
  str = "はずれ";
 }
} else {
 str = "はずれ";
}

なんだか見にくいですね。
おまけに"はずれ"を代入するところが重複しています。
これは次のように書きかえれます。
int num = 12;
String str;

if (10 < num && num < 20) {
 str = "あたり";
} else {
 str = "はずれ";
}
すっきりしました。
ここで出てくる"&&"はANDを意味し、短絡演算子と言います。
短絡演算子は次の種類があります。

&&論理積(AND)
||論理和(OR)

これでたいていの条件文は書けるんではないでしょうか。

ここで補足。
if 文の括弧の中に入る条件はboolean型です。
(真偽値、TRUEとかFALSEってやつ。ここででてきた)

つまり次のような書き方もできます。
int num = 12;
String str;

// boolean型の変数isHitに条件式を代入
boolean isHit = 10 < num && num < 20;

if (isHit) {
 str = "あたり";
} else {
 str = "はずれ";
}

まあ、通常はこんな書き方はしないでしょうが、
メソッドの戻り値にbooleanを使用する場合なんかはありますね。
演算子の説明をしてきたので、その他の良く使う演算子も紹介します。
まずは算術演算子。

+加算(足し算)
-減算(引き算)
*乗算(掛け算)
/除算(割り算)
%余算(余り)
int num1 = 10 / 2;       // 5を代入(10÷2)
int num2 = 2 + 8 / 2;    // 6を代入((8÷2)+2)
int num3 = (2 + 8) / 2;  // 5を代入((8+2)÷2)
演算順序は算数と同じですね。
(わからない人は小学校の算数を見直しましょう(笑))

あとは論理演算子。

&論理積(AND) 
|論理和(OR) 
^排他的論理和(XOR)
!否定(NOT)

これはあまり使わないかもしれませんが、"!"は良く使うので覚えておいたほうがいいです。
int num = 12;
String str;

// boolean型の変数isHitに条件式を代入
boolean isHit = 10 < num && num < 20;

// isHitでない、という意味になる
// つまり10以下、もしくは20以上の場合に"あたり"を代入することとなる
if (! isHit) {
 str = "あたり";
} else {
 str = "はずれ";
}


今回は以上です。
次回はオブジェクトの比較について書いてみようかな~
(最近blogばっかり書いてアプリ作りしてない気がするw)

【Java】コンストラクタと継承 with FF5

前回、FF5のジョブをクラスとしてインスタンス化することを書きましたが、
今回はその続きです。

おさらいがてらジョブをクラスとして宣言していきます。
public class ナイト {

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void 両手持ち() {
  // 武器を両手で持ち、攻撃力を倍増させる
 }
  ・
  ・
  ・
}
public class シーフ {

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void ぬすむ() {
  // モンスターの持つ宝を盗む。失敗することもある
 }
  ・
  ・
  ・
}
public class 黒魔道士 {

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void 黒魔法() {
  // 黒魔法を使用する
 }
  ・
  ・
  ・
}
各ジョブを見てもらうと気付くと思いますが、
「たたかう」や「ぼうぎょ」などのメソッドはどのジョブでも使用可能なメソッドで、
その内容も一致しています。
これを大量にあるすべてのジョブに実装していくのは面倒ですね。
それどころか、ゲームの仕様が変わって「たたかう」が「こうげき」に変わったらどうでしょう?
すべてのジョブのすべてのメソッドを修正しないといけません。

そこでJavaには継承という機能が用意されています。
各ジョブの共通部分をまとめた"ジョブ"というクラスを作ってみます。

public class ジョブ {

 public int lv; // キャラクターのレベル
 public int hp; // キャラクターのヒットポイント
 public int mp; // キャラクターのマジックポイント

 public ジョブ() {
  // 初期値としてlv=1,hp=50,mp=5を設定し、引数付きコンストラクタを実行
  this(1, 50, 5);
 }

 public ジョブ(int lv, int hp, int mp) {
  this.lv = lv;
  this.hp = hp;
  this.mp = mp;
 }

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void チェンジ() {
  // 隊列を変更する
 }

 public void アイテム() {
  // アイテムを使用する
 }
}
見慣れない部分があると思います。
まず3~5行目の変数はメンバ変数(クラス変数)といい、
クラス内のどのメソッド、コンストラクタでも共通で使用できる変数です。
この例ではRPGに必須のレベルやHPをメンバ変数にしてみました。

次に7行目と12行目から始まるメソッド。これがコンストラクタです。
コンストラクタはクラスをインスタンス化(newする)際に呼ばれるメソッドで、
フィールドの初期化などを主に行います。

コンストラクタのメソッド名はクラス名とし、戻り値はなし(型も記述しない)です。

[修飾子] クラス名 (引数,・・・) { }

コンストラクタは複数設定可能で、7行目は引数なしのコンストラクタ。
12行目は引数付きのコンストラクタです。
実際にインスタンス化すると次のような感じです。

public class TestFF5 {

 public static void main (String[] args){
  
  // LV.1、HP50、MP5のジョブクラスのインスタンスsirocoが生成されます
  ジョブ siroco = new ジョブ();
  
  // LV.20、HP500、MP200のジョブクラスのインスタンスkururuが生成されます
  ジョブ kururu = new ジョブ(20, 500, 200);
 }
}
イメージが湧いたでしょうか??
因みにジョブクラスの引数なしコンストラクタのところで
"this(1, 50, 5)"とありますが、thisというのは自らのことで、
ここでは引数付きのコンストラクタを示します。
つまり"ジョブ(1, 50, 5)"と同意です。

また、引数付きのコンストラクタの中で"this.lv"などここでもthisを使用していますが、
これはコンストラクタの引数のlvと区別するために付けています。
(クラスのフィールドは本来はすべて"this."をつけれるが、不要な時は省略できます)


さて、ここからが本題。
各ジョブの共通部分をまとめたジョブクラスが出来たので、
それを継承して各クラスを作ってみましょう。
public class ナイト extends ジョブ {

 public ナイト() {
  super.hp = super.hp * 1.2;
  super.mp = super.mp * 0.6;
 }

 public void 両手持ち() {
  // 武器を両手で持ち、攻撃力を倍増させる
 }
  ・
  ・
  ・
}
public class シーフ extends ジョブ {

 public void ぬすむ() {
  // モンスターの持つ宝を盗む。失敗することもある
 }
  ・
  ・
  ・
}
public class 黒魔道士 extends ジョブ {

 public void 黒魔法() {
  // 黒魔法を使用する
 }
  ・
  ・
  ・
}
public class TestFF5 {

 public static void main (String[] args){
  
  // シーフのインスタンスsirocoが生成されます。
  // このとき、スーパークラスであるジョブクラスの引数なしコンストラクタが実行され、
  // 各メンバ変数ははLV.1、HP50、MP5となる
  シーフ siroco = new シーフ();

  // スーパークラスであるジョブクラスのたたかうメソッドが実行される
  siroco.たたかう();
  
  // 黒魔道士クラスのインスタンスkururuが生成されます。
  // このとき、スーパークラスであるジョブクラスの引数付きコンストラクタが実行され、
  // 各メンバ変数はLV.20、HP500、MP200となる
  黒魔道士 kururu = new 黒魔道士(20, 500, 200);

  // 黒魔道士クラスの黒魔法メソッドが実行される
  kururu.黒魔法();

  // ナイトクラスのインスタンスrenaが生成されます。
  // このとき、スーパークラスであるジョブクラスの引数なしコンストラクタが
  // 実行され、メンバ変数はLV.1、HP50、MP5となります。
  // そのあとナイトクラスのコンストラクタが実行され、
  // ジョブクラスのhpを1.2倍、mpを0.6倍にして代入しています。
  // つまりrenaの状態はLV.1、HP60、MP6となります
  ナイト rena = new ナイト();
 }
}
クラスを継承するには、クラス宣言の際に"extends 継承するクラス名"で行います。
継承したクラス(子クラス)は継承元のクラス(親クラス、スーパークラス)の
フィールドを使用できます。

これでどのジョブからでも「たたかう」や「ぼうぎょ」を使う事が出来ます。
また、共通部分の変更が発生しても、スーパークラスであるジョブクラスを
修正するだけで、すべてのクラスで修正後のメソッドを使用できます。

上の例でナイトクラスにだけコンストラクタを設定しています。
他のジョブについては記述していませんが、この場合は引数なしの
デフォルトコンストラクタが暗黙に宣言されています。


因みに、ナイトクラスのコンストラクタ内でスーパークラスのメンバ変数に
直接あたいを代入しているが、これはあまりよろしくありません。
メンバ変数をprivate宣言し、アクセッサメソッド(ゲッター・フッター)を使うほうが良いです。
今回は説明前なので、あえて直接代入とさせています。(そのほうがわかりやすいと思って)


インスタンス化の際のコンストラクタの実行順としては、
まずスーパークラスのコンストラクタが実行され、
そのあと子クラスのコンストラクタが実行されます。


長々と書いてきましたが、継承について少しは感じがつかめたでしょうか?
細かいことを書けば、大量の説明が必要になるので、書きませんが、
詳しく知りたくなった人は古本屋さんとかでJavaの本を手にとって見てはいかがでしょう??

次回は条件文について書こうと思います。
(ここは流石にFF5は無理かな~)

Javaを始めるなら。。。

sirocoがJavaを始めた時に参考にした本です。
他にもJavaの本は持ってるけど、結城さんのは読みやすいと思います。


2012年3月23日金曜日

【Java】クラスとインスタンス with FF5

クラスとは同様の状態・振る舞いをもつオブジェクトの共通部分を集めて
1つの型を構成することです。
ここでいう状態はクラス変数(メンバ変数)などを示し、
振る舞いはメソッドを示します。

固く書いてもわかりずらいので、最近sirocoがやっているゲーム「FF5」を
例に挙げて説明してみます(笑)

FF5にはジョブというシステムがあります。
ナイト・シーフ・白魔道士などなど。
これら各ジョブをクラスに表してみます。
public class シーフ {

}
クラスの宣言は以下のようになります。

[修飾子] class クラス名 { }

上の例ではpublic(どこからでも使用できる)なシーフというクラスを宣言しています。
クラスの持つ状態や振る舞いは "{" と "}" の間にコーディングします。

ジョブには特有のアビリティがありますので、
それをメソッドとしてあらわしてみます。
public class シーフ {

 public void かくしつうろ() {
  // ダンジョンなどの隠し通路が見えるようになる
 }
 
 public void とんずら() {
  // 戦闘から逃げる。逃げられないモンスターもいる
 }
 
 public void ダッシュ() {
  // キャンセルボタンを押しながら移動すると、2倍の速度で動ける
 }
 
 public void ぬすむ() {
  // モンスターの持つ宝を盗む。失敗することもある
 }
  ・
  ・
  ・
}
メソッドの宣言は以下のようになります。

[修飾子] [戻り値の型] メソッド名 { }
メソッドの内容については、また別の機会に。

さて、上で宣言したシーフクラスは1つのオブジェクトですが、
オブジェクトそのものでは使用できず、
インスタンス化をして始めて使用可能となります。
(staticなフィールドは別ですが)

インスタンス化の例を挙げてみます。
public class TestFF5 {

 public static void main (String[] args){
  
  // シーフクラスのインスタンスsirocoを生成
  シーフ siroco = new シーフ();
  
  // とんずらメソッドの使用
  siroco.とんずら();

  // シーフクラスのインスタンスkururuを生成
  シーフ kururu = new シーフ();

  // ぬすむメソッドの使用
  kururu.ぬすむ();
 }
}
てな感じです。
変数やメソッドをクラスとして宣言し、インスタンス化することで、
sirocoとkururuのそれぞれで、オブジェクトのフィールド(変数やメソッド)を
使用できるようになります。


クラスとインスタンスについては、こんなところで。
次回以降でもう少し掘り下げて説明していきます。

。。。勿論、FF5を使ってね(笑)

2012年3月22日木曜日

【Java】変数の宣言と値の代入

変数はプログラム中で使用する変動する値のことで、
宣言をすることで使用可能となります。
Javaの変数の宣言は次の形で行います。

[型] 変数名;

int i;     // int型のiという変数を宣言
double d;  // double型のdという変数を宣言
Object o;  // Object型のoという変数を宣言
String s;  // String型のsという変数を宣言

変数の宣言はプリミティブ型でも参照型でも同様となります。
実際には[型]の前に修飾子を付けることができますが、
複雑になるので別の機会に。

続いて値の代入を見ていきます。
代入の方法はプリミティブ型と参照型で異なります。
(前回説明したところです。⇒プリミティブ型と参照型

まずはプリミティブ型。
値を直接代入します。
int i = 123;     // int型の変数iに123を代入
double d = 1.23;  // double型の変数dに1.23を代入

次に参照型。
インスタンスを生成して代入します。
(インスタンスについては次回詳細を説明します。)
もっとも基本的なインスタンスの生成は new クラス名() で行います。
Object o = new Object(); // Date型のdateという変数を宣言

なお、String型のみが参照型の中でも特別扱いされています。
Stringは、不変の(内容が変更されない)文字列を扱うクラスですが、
あまりに良く使うクラスの為、"(ダブルコーテーション)で括った文字列を直接代入できます。
// String型の変数s1に"abc"という文字列を代入
String s1 = "abc";

// これはs1とは別のオブジェクトとなる(参照先が異なる)
String s2 = new String("abc");

// Stringは不変なのでnewでインスタンス化するのは無意味
String s3 = new String();

こんなとこかな。

【こんにちは赤ちゃん】ver2.1.0 リリース



こんにちは赤ちゃん
⇒マーケットはこちら


更新内容
今まではウィジェットをクリックした場合のみ遷移させていた赤ちゃんの様子画面へ、
設定画面からも遷移出来るように変更しました。


お知らせ
前回のバージョンアップから、「こんにちは赤ちゃん」使い方ページも更新しています。
こちらからどうぞ。


最近、ウィジェットが起動しないというコメントが多くなってきたので、
思い切って設定画面から遷移させてみました。
上記不具合の暫定対策ですね。

本当はウィジェットが設定できないHOMEアプリとかにしてるのが
原因だと思うんだよな~
現に同一端末で普通に使えている人がたくさんいるんだし。。。