クラスメソッドとインスタンスメソッドの付け足し

会社の先輩から、簡単に教えてもらってパッとしたのでメモしておきます☆

インスタンスメソッド
インスタンスごとにやることや結果が変わってくるようなメソッド。

例えば、食べ物が腐っているか腐っていないかを判定するフラグを
引数としてもつメソッドがあるとします。そのフラグには、
食べ物が腐って無い場合は0をセットし、腐っていたら1をセット
するような決まりにします。0か1のどちらがセットされたことに
よって、その後の処理が変わってくるようなメソッドをインスタンス
メソッドにします。このように、インスタンスによってやることや結果
が変わってくるメソッドをインスタンスメソッドにするそうです。


●クラスメソッド
インスタンスによらず、いつも同じことしかしないメソッド。

例えば、四角形の面積の計算は『縦×横』なので、縦と横の長さを
引数とするメソッドを作れば、面積の異なる四角形でもいつも
四角形の計算しかしません。つまり、インスタンスによってやること
は変わらないのです。

インスタンスとクラス

もうプログラミングを始めて半年も経つのに、インスタンスメソッドとクラスメソッドの
概念が結構あやふやです。なので、本とか読んで自分なりにわかったことをこの機会にま
とめておこうと思います。

インスタンスフィールドとクラスフィールド

インスタンスフィールド

フィールドはクラスが持つ変数。
インスタンスを生成すると、そのフィールドはインスタンス単位で発行されます。
なので、インスタンスAとインスタンスBのフィールドは同じ名前でも全く関連が
ありません。また、『this.フィールド名』と書くと、今生成したインスタンス
フィールドという意味になります。


クラスフィールド

クラスフィールドはstaticが付いたフィールド。
つまり静的フィールドなので、インスタンスにごとに生成されるフィールドではなく、
そのクラスにたった一つしかないフィールドです。
『this.フィールド名』と書くとコンパイルエラーになります。
なぜなら、thisはインスタンス自体を示しているので、クラスフィールドを示して
いることにならないからです。

このフィールドはインスタンスごとに初期化されては困るような、また、クラスの
中で保持しておきたいデータなどに用いるみたいです。

ゲームで例えるなら、

今生きているプレイヤーの人数を保持するのがクラスフィールド(インスタンス全体を把握)
今のプレイヤーが生きているかどうかを保持するのがインスタンスフィールド(個々のインスタンスを把握)

もし生きているプレイヤーの人数を保持するフィールドがクラスフィールドでなく、インスタンスフィールドだったら、
インスタンスを生成する度に初期化されてしまうので、ずっと初期値と変わらない状態になります。

インスタンスメソッドとクラスメソッド


インスタンスメソッド

概念としては、インスタンスフィールドと一緒です。
現在のインスタンスの状態を調べたり、現在のインスタンスに対して処理を行ったりするメソッド
(つまり、インスタンスフィールドを使って計算を行うメソッド)のことを言います。


クラスメソッド

staticが付いたメソッドです。
そのクラス変数(フィールド)に対して計算や処理を行ったり、そのクラスのインスタンスの中から
ある特定のインスタンスを見つけ出すメソッドのことを言います。



わたしの中で、概念的なものはわかっているのですが、実際に自分で使い分けろと言われても
どういう時に使い分けたらいいのかがわからないのでパッとしません。。。。
会社の先輩が書いたソースをみると、共通処理をクラスメソッドにしています。
でも、共通処理でもクラスメソッドにできないものもあるみたいで・・・・・。
その違いは未だよくわからず。。。。
完全に理解するには、まだまだ勉強が必要です(>_<)

Iterator

久々の更新です。

Iteratorについて調べてみました。

あるコレクションからデータを取り出すためには、いくつかの方法があります。
例えば、ArrayListから要素を取り出すときはfor文でこんな風に取り出します。

ArrayList<String> array;
array.add("りんご");
array.add("ごりら");
array.add("らっぱ");
int i;

for ( i = 0; i < array.size(); i++ ){
			
    System.out.println("中身:"+ array.get(i));
}

でも、これだと、いくつか問題点があります。

☆ ArrayListの中身を簡単に変更できてしまう
☆ 取り出したいものの型(今回はArrayList)によって、使用するメソッド(今回はget(i))が変わってきてしまう

これではデータを隠蔽することができず、大問題です。



そこで便利なのがIterator


これは、さきほどの問題を解決することができます。
要素を取り出す側からは、要素を変更することができませんし、何の型かわからなくても
要素を取り出すことができます。
しかも、for文では最初の要素から最後の要素まで順に取り出すことしかできませんが、
Iteratorは色んなメソッドがあり、逆方向からも要素を取り出すことができます。

Iterator<String> it = array.iterator();
while (it.hasNext())
{
     Object val = it.next();
     System.out.println(val.toString());
}

☆hasNext()
次の要素が存在するならtrueを、存在しないならfalseを返す


☆next()
要素の添え字をひとつ進めて次の要素をポイントする


そのほかにも色んなメソッドが。。。。

☆reset()
添え字をコレクションの始点に戻す


☆current()
添え字を進めないで、現在の要素を返す


色んな機能があるんですね♪

DataGridの中のChekBox

DataGridはdataProviderにセットされたデータを
表示することができます。
ただ単に、文字をDataGridに表示させるだけならば
簡単なんですが、ユーザーによって表示内容が変え
られてしまうものを表示するときは一苦労しなくて
はなりません。


例えば、DataGridの中にCheckBoxを表示させる例が
あります。
CheckBoxはユーザーによって、チェックを入れられ
たり、はずされたりしますよね?
なので、しょっちゅう表示内容が変えられてしまいます。
表示内容が変わるということは、表示する元のデータで
ある、dataProviderの中のデータも変更させなくてはな
りません。初期表示でチェックがはずされていたら、
DataProviderの中のチェックボックスに関するデータは
falseになっているはずですが、ユーザーによってチェッ
クボックスにチェックを入れられてしまったら、
dataProviderのデータもtrueにしなくてはなりません。


具体的に説明すると、下のActionScriptのソースを見
て下さい。
houseという変数がありますが、これはメイン画面の
DataGridのDataProviderにセットされてるデータです。
さらにこの中にはchkという要素があり、これはDataGrid
の4番目のカラムで「選択」というカラムがdataFieldと
して指定しているデータです。
このchkはチェックボックスのselected(チェックの有無
を決めるプロパティ)をtrueにするかfalseにするかを指
定しています。デフォルトではfalseにしているので、
チェックボックスの初期表示はチェックがはずされた状態
になります。


しかし、ユーザーによってチェックが入れられてしまったら・・・。
このchkの内容を書き換えなくてはなりません。
なぜなら、DataGridはdataProviderの値を見ているわけです
から、表示内容が変更されたらdataProviderの内容も書き換
えてあげないと、表示内容も変更されないからです。
なんだかややこしいですね。
簡単に説明すると、下の様な流れになります。


1.ユーザーがチェックボックスにチェックを入れる
         ↓
2.dataProviderのchkの値がfalseからtrueになる
         ↓
3.chkがfalseからtrueに変更されたことをDataGridが
  dataProviderによって参照する
         ↓
4.チェックボックスにチェックが入る


次に、その作業をどこで行っているかです。



DataGridにコンポーネントを組み込む時は、itemRenderer
というものを使います。メイン画面のmxmlのDataGridの
DataGridColumnに書いてあるプロパティです。
ここに、自分で作ったカスタムコンポーネント(ChekBoxEx)
のパスを入れてあげます。
これでチェックボックスは表示できます。



さらにCheckBoxExについてですが、ここに書いてあるCheckBox
にchangeというイベントについて説明します。これは、チェッ
クボックスがユーザーによっていじられた時に発生するイベン
トです。
この中に書いてある式は、「ユーザーからいじられたら、データ
プロバイダで参照しているchkというプロパティに、このチェック
ボックスのselectedの状態を代入しろ」という意味です。
チェックボックにチェックが入ったら、このチェックボックス
selectedはtrueになるので、このtrueがchkに代入されるんです。
ここでdataProviderの値は初めて変更されるわけです。
上のフローでいう、2の部分ですね。



さらに、CheckBoxExのrootになっているHBoxですが、ここに
dataChangeイベントがあります。
これはdataProviderの値が変更された時に発生するイベントです。
先ほどのchengeイベントによってdataProviderが参照しているchk
の値は変更されましたから、そのタイミングでdataChangeイベント
は発生します。
ここの式では、「もしdataProviderが参照しているchkの値がtrue
になっていたら、このチェックボックスのselectedにtrueを入れろ」
という意味です。
chkは今trueに変更になっているので、trueをチェックボックス
selectedに代入しているわけです。ここで初めてチェックボックス
にチェックが入るわけです。
上のフローでいう、3と4の部分ですね。


チェックボックスひとつをDataGridに表示させたいだけなのに、
こんな大変なんて面倒臭いです。
この方法はチェックボックス意外にTextInputなどのデータが
ユーザーによって書き換えられた時も使えるので、参考にし
てみてください☆



ソース

☆メイン画面のmxml














☆メイン画面のActionScript(Acstion.as)☆

package test
{
	import mx.collections.ArrayCollection;
	import mx.collections.XMLListCollection;
	import mx.controls.Alert;
	
	public class Action
	{    
        [Bindable]
        public var house:XMLListCollection = new XMLListCollection(
			new XML(<root>
				 <house>
				 	<date>2009/10/24</date>
				 	<contents>光熱費</contents>
				 	<price>3000</price>
					<chk>false</chk>
				 </house>
				  <house>
				 	<date>2009/10/25</date>
				 	<contents>洋服</contents>
				 	<price>2000</price>
					<chk>false</chk>
				 </house>
				 <house>
				 	<date>2009/10/26</date>
				 	<contents>家賃</contents>
				 	<price>60000</price>
					<chk>false</chk>
				 </house>
			</root>).house);
			
	}
}

☆itemRendererが参照しているコンポーネント(ChechBoxEx.mxml)☆




画面

簡単なクイズアプリ♪

FlexBilderは60日間のお試し期間が終わってしまうと、お金を払わなければ使えなくなってしまうので、

imai78さんからオススメいただいた、FlexDevelopという無償のツールをインストールしてみました★

なんら使い心地は変わらないです♪


今回はRadioButtonとAlertの使い方でクイズが作れる事を知ったので、覚え書きします!

ソース


import mx.controls.Alert;




Alert.show(answer3.selected?'正解!!':'不正解・・・。', '結果')"/>



実行結果

☆初期画面☆


☆正解アラート☆


☆不正解アラート☆


説明

ポイントは赤で示したAlert.showの部分です!

Alert.showはアラート画面を出す為だけに使っていましたが、色んな使い方ができるんですね!


一つ目の引数(answer3.selected?'正解!!':'不正解・・・。')


RadioButtonのid名がanswer3のものが選択されたら、「正解!!」とアラートに表示させます

つまり、「東京」が選択されたら「正解!!」が表示されます。

また、それ以外のものが選択されたら「不正解・・・。」を表示させることができます。



二つ目の引数('結果')


アラートの左上に表示される題名を設定することができます。

画面のキャプチャ

こんばんわ!最近、勉強がはかどらないhodoshimaです・・・。
定時に帰れるのに、家に帰るとゴロンとしてしまいます・・・。
勉強する習慣をつけなければ(>_<)

ちょっと前にやったことになってしまいますが、今回はFlexによる、画面のキャプチャについて書いてみたいと思います☆
画面のキャプチャとは、Ctrl+PrtScrで行うように、画面をコピーすることです!
この作業をFlexActionScriptを用いて作ることができます!

いきなりソースだけを書いてしまいますと・・・

ActionScriptファイル(Test.as)

var scimg:Image = new Image();
//mxmlで書いたviewのことです
var view:TestView;

/**
*画面キャプチャメソッド
**/
public function doCapture ():void
{
var screen:BitmapData = new BitmapData(this.view.width,this.view.height);
//viewをBitmapData型オブジェクトに書き出す(画面のキャプチャ)
screen.draw(UIComponent(this.view));
//BitmapData型をBitmap型でラップする
var bmp:Bitmap = new Bitmap(screen);
//キャプチャした画面を半分に縮小(横)
 bmp.scaleX = 0.5;
//キャプチャした画面を半分に縮小(縦)
bmp.scaleY = 0.5;
//印刷するイベントdoPrintの登録
scimg.addEventListener("added",doPrint);
//Image型のオブジェクトにBitmap型のオブジェクトをいれる
 scimg.addChild(bmp);
}

/**
*キャプチャした画面の印刷
**/
 private function doPrint(event:Event):void 
{
 var pj:PrintJob = new PrintJob();
if(pj.start()) {
pj.addPage(scimg);
	pj.send();
} 
}

次にこのソースの意味を説明します!

●BitmapData
BitmapDataオブジェクトは数値データなので、画像化するためにはこのBitmapDataオブジェクトをBitmapオブジェクトでラップする。

●draw
Flash Player のベクターレンダラを使用して、source 表示オブジェクトをビットマップイメージ上に描画します。BitmapDataのメソッド。
これを使うことで、指定した画像をBitmapDataとして描画することができる。

●UICompornent
id, left, widthなど、mxmlで使用されるコンポーネントの親的なクラス。これらのコンポーネントはすべてUICompornentを継承して作られている。
UICompornet(this.view)と書くと、mxmlで書かれているviewのことを指す。

●Image
実行時に、JPEGPNG、GIF、および SWF のファイルを読み込むために用いるクラス。

●ScalXとScalY
画面をそのまま縮小、拡大する。0.5は半分に縮小、1はサイズを変更しない。


キャプチャした画面を印刷してみたところ、なぜかパソコンの画面からはみ出してしまう程大きかったので、
ScalXとScalYで半分に縮小してみたのですが、Bitmap画像であるために、画像が粗くなってしまいました。

そこで、Bitmapクラスのコンストラクタに引数として割り当てられている、pixelSnappingとsmoothingを使ってみました。

こんな風にBitmapクラスのコンストラクタには3つの引数があります。

Bitmap(bitmapData:BitmapData = null, pixelSnapping:String = "auto", smoothing:Boolean = false)

これを使ってさっき上で書いたソースをいじくり・・・

var pixelSnapping:String = "auto";
var smoothing:Boolean = false;

//BitmapData型をBitmap型にする
var bmp:Bitmap = new Bitmap(screen, pixelSnapping, smoothing);

このように書くことで粗くなった画像は滑らかになると参考サイトには書かれていたのですが、
粗いまま解消できませんでした(>_<)
(参考サイトhttp://livedocs.adobe.com/flex/2_jp/langref/flash/display/Bitmap.html)

どなたか解消法を知っている方がいらっしゃったら、教えて下さい!

ArrayとArrayCollectionの違い

最近は会社である課題を出され、それを特に時間制限もなく
プログラムの理解を深めるために勉強させて頂いております!


なかなか難しい課題を出されるのですが、ネット上には答え
が色々と転がっているもので・・・。それをコピペしていると
なんとなく出来てしまったりします。


それも有難いのですが。

やっぱり、理解するために頂いている時間なので、
それでは意味が無いし、今後の自分のためにもよろしくない
ということで。


今回は、会社の課題で疑問に思ったFlexのArrayとArrayCollection
の違いについて調べてみました(*^_^*)v

javaではArrayやArrayListなどが配列を扱うクラスとして利用することができました。
Flexで用いるActionScriptという言語では、ArrayとArrayCollectionというクラスが
あります!なので、javaの時と混同してしまい、頭が混乱気味です。。。


まず、下のソースの通り、書き方としては、全く2つの間に違いは見られません・・・。



【Arrayの場合】

var ArrayData:Array = new Array();

ArrayData = [{data1:"花子",data2:"21才"},{data1:"二郎",data2:"18才"}];


【ArrayCollectionの場合】

var ArrayData:ArrayCollection = new ArrayCollection();

ArrayData = [{data1:"花子",data2:"21才"},{data1:"二郎",data2:"18才"}];


何が違うんでしょ?


調べてみると・・・。

ArrayCollection クラスは,ICollectionView または IList インタフェースのメソッドとプロパティを使用して,アクセスおよび操作できるコレクションとして配列を公開するラッパークラスです。

という説明が。。。

私には言っていることが難しいですし、よく理解できませんでした(>_<)


もっと調べてみると!

ArrayCollectionは、Arrayを内包する
ArrayCollectionは、内包したArrayをいじること無く、ソートをしたりできる
ArrayCollectionは、内包したArrayのView
ArrayCollectionは、bindableなども利用できる(?)

参考サイトhttp://actionscript.g.hatena.ne.jp/d4-1977/?of=40


これなら少しわかります!

そして、さらに・・・



【Array】
*データ保存のために使用する
*dataProviderとしては使用できない
*一度はバインドできるがデータ操作ができないため、データを入れ替えても画面に反映されない


【ArrayCollection】
*dataProviderとして使用する
*データ操作を行うことができるので、データが変更されるとそれが画面に反映される
参考サイトhttp://www.necst.co.jp/product/ibiz/column/flex/chap4_3.html




どうやら、ArrayよりもArrayCollectionは便利なようです。


具体的にどんなことが便利だというと。


私が理解できたのは、

ArrayCollectionの方がArrayよりも多くのメソッドを持っている!


例えば、すでに配列の中身を作っていた場合、
Arrayでは元のデータを書き換えるしかないですが、
ArrayCollectionでは、以下のメソッドを使えば好きな時に追加する事ができたり、好きなデータ
を取得出来たりします。



//指定されたアイテムをリストの末尾に追加する。
addItem(item:Object):void

//指定されたインデックス位置にアイテムを配置する。
setItemAt(item:Object, index:int):Object

//指定されたインデックス位置にあるアイテムを取得する。
getItemAt(index:int, prefetch:int = 0):Object





また、DataGridという、HTMLではTableと同じ様な機能を持つMXMLのタグがあります。
これは、使いたいデータを指定する時には以下の様に、dataProviderというものを
使用します。







でもdataProviderを使う際には、Arrayで作ったデータを指定することはできません。
ArrayCollecitonで作ったデータなら使うことができます。

実際の使い方の違いを見てみると・・・


【 Array配列を使用した例 】














【 ArrayCollection配列を使用した例 】










参考サイトhttp://air-flex.jugem.jp/?eid=31



このように、ArrayのデータをdataProviderで指定したい時は、
Arrayで作ったデータをArrayCollectionにキャストしています。
こうすることで、dataProviderにArrayのデータを指定すること
ができるようです。



他にも色々利点があるようですが、
今回はこの辺で♪