Ceylonモジュール作成やクラスなどの基本コード

Ceylonのコードを書くときの基本的な書き方をやります。

まずはCeylonのプロジェクトが出来ている前提です。
出来ていない人は  [Ceylon環境の作り方](http://qiita.com/newta/items/d84200874645fa5cef26)からどうぞ。

#まずモジュール作成
New > Ceylon Module
からモジュール作成のダイアログを開きます。
Module nameに入力した値はパッケージ名になります。
Runnable compilation unitに入力した値は実行のファイル名になります。

![スクリーンショット 2013-12-04 13.25.04.png](https://qiita-image-store.s3.amazonaws.com/0/17213/0b1bb02e-5116-2ca3-1189-0a5ef6ff8c50.png)

上記のように入力して完了すると
以下のファイルが作成されます。
module.ceylon
package.ceylon
run.ceylon

module.ceylonにはモジュールで利用するライブラリなどの読み込み設定などを書くようです。
package.ceylonにはパッケージのドキュメントを書いたりするとこみたいです。
Javaでのpackage-infoみたいな感じ？
run.ceylon通常のCeylonソースコードを書いて行く場所です。

run.ceylonを開くと

```ceylon
shared void run() {    
}
````

と書かれているのでそのメソッドの中にバリバリ書いて行けばOKです！

#クラスの作り方
と言うことでちょっとずつ実践的な感じにするために
絶対必須なクラス定義のしかた。

前回の[Ceylonの良いとこ説明コードその１](http://qiita.com/newta/items/41d5bc6f25b0ba8d9cc6)で触れたとこは
特に説明しないのでvariableとかは前回の投稿を見てね。

と、言うことで早速クラス書いちゃいます。

```ceylon
shared void run() {
    
    value counter = Counter();
    print(counter.inc());  // -> 1
    print(counter.inc());  // -> 2
    print(counter.inc());  // -> 3
}

class Counter() {
	
	variable Integer i = 0;
	
	shared Integer inc() {
		return ++i;
	}
}
````


run.ceylonファイルに
Counterクラスを書いてみました。
なんとCounterクラスをインスタンス化するのにnewがありません！
最初は違和感があるけど、慣れればあんまり気になりません。

ただ、ちゃんと大文字からクラス名を付けないとクラス生成してるのか
メソッドを呼んでるのか分かんなくなりそう。

まあJavaをやっていれば既に雰囲気はつかんでると思います。

#メソッド、公開変数、などのスコープ
Counterの保持する「i」はクラスの外には見えません。
クラス外に見えるようにするにはsharedを付けます。
protectedなスコープを持つ変数は定義出来ません。

次にincメソッドですがsharedがついているのでクラス外から呼び出すことが出来ます。
外すとクラス内からのみアクセス可能なメソッドになります。

最後にクラスにsharedを付けるとどこからでもクラスを参照することが出来ます。
何も付けていないときは同じパッケージ内の場所からのみ参照出来ます。
ファイルが別でもパッケージが同じであれば参照可能です。



Javaのprotectedとパッケージプライベートの扱いって微妙でしたよね。。
どう使っていいか困ったこともあります。。
でも、Ceylonでは完全に割り切ってる感じでシンプルだなと。

#デフォルト引数
Ceylonではメソッドにはデフォルト引数が使えます。
incメソッドに引数に与えた数値分増加出来るようにしてみました。

```ceylon
	shared Integer inc(Integer add=1) {
		return (i += add);
	}
````

デフォルト引数が可能にはなっていますが、
代わりにJavaでは出来たメソッドのオーバーロードが出来なくなっています。

ま、良いんじゃないかな。デフォルト引数値はC#やScalaを指くわえながら見て
欲しいなーと思っていたのであった方がいいよね！


#コンストラクタ
まず、クラスがメンバを持つ場合、全て初期化しないとコンパイルエラーとなります。
今回は i に 0 をセットしてます。

この辺もCeylonの細やかな厳しさを感じる。
Javaにグッときてる人は逆にいいんじゃないかなと思う。

ここではコンストラクタでカウンターの初期値を設定して生成出来るようにしてみましょう。

```ceylon

class Counter(variable Integer i=0) {
	
	shared Integer inc(Integer add=1) {
		return (i += add);
	}
}
````

はい。メンバ変数で定義してたヤツが居なくなりました！
なんと、コンストラクタで引数として受け取った変数は
自動でメンバ変数として保持されます。
外部から参照されるようにしたい場合はこの「i」にsharedを付ければ
クラス外から参照出来るようになります。

ちょっと楽チン。

コンストラクタで何かチェックしたいときは
そのままコードを書けばOK.
初期値としてマイナスの数値が入った場合エラーにするようにすると

```ceylon

class Counter(variable Integer i=0) {
	assert(i>-1);
	
	shared Integer inc(Integer add=1) {
		return (i += add);
	}
}
````

こんな感じ。
マイナス値のときに自動で0にしちゃうようにしてみると

```ceylon
class Counter(variable Integer i=0) {
	
	if(i < 0) {
		i = 0;
	}
	
	shared Integer inc(Integer add=1) {
		return (i += add);
	}
}
````

こんな感じ。
メソッドなしでロジックやら初期変数が定義されたりですね。

複雑なコンストラクタが生まれるよりは１個のコンストラクタに集約されて
記述も身軽になって良いかも？？

でもこの辺はJavaと感覚がちょっと違う感じかなぁ。
ここは使い込んでみないと良いのか悪いのか分からないかも。

#setterとgetter

setterとgetterの扱いが変わっています。
Javaでは命名規則でsetXxxxx、getXxxxというメソッドが
プロパティのsetter、getterと言う扱いでしたが、
Ceylonでは以下のように宣言します。

```ceylon
	shared Integer nowCount {
		return i;
	}
	
	assign nowCount {
		 i = nowCount;
	}
````


getterは値を返すだけのものを付ければOKです。
この宣言は参照は出来ても代入は出来ません。
代入するにはsetterの宣言が必要です。
参照はこのように呼び出してコンソールに出力したり出来ます。

```ceylon
print(counter.nowCount);
````

setterはassignで宣言します。sharedは必要ありません。
assignを付けると自動的に公開状態になります。
以下のように代入で呼び出すことが出来ます。

```ceylon
counter.nowCount = 10;
````

ちなみに１行のときはこんな感じで書くことが出来ます。

```ceylon

	shared Integer nowCount => i;
	
	
	assign nowCount => i = nowCount;
````

やばいscalaっぽくなってきた。
でも、Java8も来そうだし、アリですよね！


#Javaでの宣言との比較

java -> ceylon
public -> shared
protected -> メソッドは無印で同じパッケージからアクセス可能
private -> 変数は無印でクラス内からでのみアクセス可能

コンストラクタは１つだけ！
デフォルト引数値を指定出来るようになった！

gettersetterはメソッド命名規則ではなくassignでsetterを、getterは別参照名で。


#まとめ

Javaと書き方が違うなーって感じるところもちょいちょい出てきました。
でも、Javaで微妙だ・・・って思っていたところが順々に改善されている感じが分かります。

スコープ、そしてデフォルト引数とsetter、getterそしてコンストラクタでした。
改善されているなぁ。

読み口はあまり変わらないまま読めるかなーと思います。

まあ、コンストラクタ内での処理とか、getterとsetter周りでは
scalaとか読んでればあんまり違和感無いかも知れないけど
Javaから見るとちょっと違和感が出てきたかも？

それでもJavaっぽい読み味は失われてません！
でも、ちょっと慣れが必要になって来る文が出てきたかも。

もうちょっとだけ頑張ってみて！