¥chapter{関数}


関数(function)は、プログラムの一部をモジュール化するための代表的な手段です。名前が示すとおり、数学の関数 $y = f(x)$ をモデルとして、引数 $x$ に対して結果$y$が得られるという形でプログラムのモジュール化とパラメータ化を実現する。

Konohaにおける関数は、単にScript} クラスのメソッドです。しかし、関数のアイディアはオブジェクト指向プログラミングより古く、クラス概念を導入しなくても利用できる伝統的なモジュールであるため、オブジェクトを意識しないで呼び出せるメソッドを「関数」と呼んでいます。関数をファーストクラスオブジェクトとして扱う手法を「クロージャ」と呼んでいます。

== 関数を定義する}

プログラマは、既存の関数を利用するだけなく、新しい関数を自由に定義することができます。Konohaでは、関数定義のための特別なステートメントは用意されておらず、C/C++, Java と同様に、型宣言にパラメータとモジュールを追加する形式で行う。

¥begin{quote}
$T$ $f$ ($T_1¥; p_1$, $T_2¥; p_2$, ...)  | $stmt$
¥end{quote}

$T$型の評価値を返す関数は、Konohaの名前規則にしたがい、英小文字で始まる名前$f$を持ち、0個以上のパラメータ(変数）$p_1, p_2, ...$をとるように定義する。モジュール本体は、続けて $stmt$ の部分に書き、ここでは一般的にステートメントブロックを用いてプログラムを構成する。

次は、$f(x) = x + 1$ という式を関数でモジュール化した例です。関数の評価結果は、return文で書く。

{{{
int f(int x) { 
   return x + 1; 
}
}}}

一旦、関数を定義すると、関数をコール演算子で呼び出すことで、何回でもモジュール化されたプログラムを再利用することができます。

{{{
>>> int f(int x) { 
...    return x + 1; 
... }
>>> y = f(1)
>>> y
2
>>> f(2)
3
}}}

プログラミング言語における関数は、引数や戻り値に対して「型」が必要な点が特徴的であるといえる。Konoha は、C/C++, Javaなどの静的な型付け言語と同様に、関数定義のときに、これらの型を明示的に宣言することになっています。原則、パラメータや戻り値の型推論は行わない。

これは、変数宣言における型推論に比べ、極めて保守的なスタンスをとっているように思われるかも知れない。関数（及びメソッド）は、異なる開発主体が開発するソフトウェア境界のインターフェースとなり、今日のソフトウェア開発ではインターフェースを明示的に仕様化することが望ましいとされています。更に、型検査などで機械的に検査されることがもっと望ましいとされています。そういうわけで、Konohaの関数定義では、しかし、プログラミングのしやすさよりも、ソフトウェア工学的な実践面を重視した言語設計を採用しています。

=== function文}

Konohaは、動的な型付けを可能とするAny}型を持っているため、型宣言なしの関数定義もそれらの型をAny}型として扱うことで推論なしに定義可能です。したがって、次のようなJavaScript風の関数定義もそのままかくことができます。

{{{
function f(x) { 
   return x + 1; 
}
}}}

注意： Konohaでは、function文は、無名関数を定義するときに用いることを前提に導入されています。したがって、戻り値の型が決定的であれば、型推論されます。詳しくは、「第¥ref{closure}章 クロージャ」を参考にして欲しい。

== return文}

リターン


=== 戻り値*}

モジュールの処理が終れば、その処理内容を評価結果として返すことができます。これを戻り値(return value)、もしくは返り値と呼ぶ。$T$は、戻り値の型であるが、void}型を指定すれば特定の値を返さない関数も作成することができます。

== パラメータ}

関数の引数は、モジュール化されたプログラムの振る舞いをかえることに役立っています。そのため、これをモジュールのパラメータ化と呼び、関数の引数のことを「パラメータ(parameter)」と呼ぶこともあります。

=== 参照渡し}

関数の引数は、モジュール間のデータをやり取りするインターフェースになります。プログラミング言語の教科書を読めば、値渡し(call by value)、参照渡し(call by reference)、名前渡し(call by name)の３種類存在することになっているが、

Konoha は、結論から言えば、全て参照渡し(call by reference)です。理由は、"Everything is an Object"の世界であり、関数コールの度にオブジェクトをコピーするのはコストが大きすぎるためです。オブジェクト自体の代わりに、オブジェクトの参照、つまりオブジェクトのポインタを渡すことで、効率よい関数コールを実現しています。

{{{
>>> void f(String t) { print %p(t); }
>>> s="a"
>>> print %p(s)
[(shell):3] "0x6cc00"            // s と
>>> f(s)
[(shell):4] "0x6cc00"            // t は同じポインタ
>>> 
}}}

参照渡しで注意すべき点は、関数内部でオブジェクトの値を変更すると、関数を呼び出した外部でもその変更が継続することです。(関数の外と内で、同じオブジェクトを参照しているから当たり前といえば、当たり前です。)

{{{
>>> void g(Array a) {
...   a << 1;
... }
>>> Array list = [];
>>> list
[]
>>> g(list)
>>> list                         // 関数内のリスト操作が残る
[1]
}}}

注意：Int}, Float}, String} オブジェクトは、不変オブジェクトなので、関数内で変更しても、そのとき実際はオブジェクトのコピーが行われています。そのため、関数内部の変更によって外部のオブジェクトまで変更されることはない。

=== 可変長パラメータ**}

Konoha は、可変長変数を採用することができます。

=== パラメータ初期値*}


== 関数内同一スコープ}

Konoha は、C/C++ や Javaとは大きく異なり、ブロックレベルの変数スコープをサポートしていない。関数内で宣言された全ての変数は、どこで宣言されても関数内で利用できます。ただし、変数宣言より先に変数を使うことはできない。

% Unlike C, C++, and Java, Konoha does not have block-level scope. All variables declared in a function, no matter where they are declared, are defined throughout the function. In the following code, the variables i, j, and k all have the same scope; all three are defined throughout the body of the function.

例えば、次のコードにおいて、変数 k|, j| は、スコープ内として扱われます。

{{{
void test(int n) {
   int i = 0;
   if(n > 10) {
      int j = 0;
      for(int k = 0; k < n; k++) {
         print k;
      }
      print k;                    // スコープ外ではない
   }
   print j;                       // スコープ外ではない
}
}}}

次のような例外処理のコードを書くときも都合がよい。

{{{
try {
   InputStream in = new InputStream("file.txt");
   for(String line from in) {
      print line;
   }
}
catch(IO!! e) {
   print format("Error at %d", in.line);
}
finally {
   in.close();
}
}}}

また、Konoha は同一スコープ内であっても同じ型であれば、何回、型宣言を行ってもエラーとならない。そのため、コピー＆ペーストする場合も支障とならない。

== 関数呼び出し}

コール演算子()|は、メソッド/関数 f|、コンストラクタnew C|、もしくはフォーマッタ%f|に続いて用いられ、メソッド/関数を呼び出すときに用います。括弧()|の中には、0個以上のパラメータ/引数を,|で区切って与えることができます。コール演算子の評価値は、メソッド/関数の戻り値となります。(ただし、メソッド/関数の戻り値void 型の場合は、評価値はない。)

{{{
f()                        // 関数 f()のコール
o.f()                      // o のメソッドf()をコール
new C()                    // クラスCのコンストラクタ
%f(o)                      // o のフォーマッティング
}}}

コール演算子で与えられるパラメータは、メソッド/関数ごとに個別に定義されています。定義と異なるパラメータでコールしようとしたときは、型エラーとなります。

{{{
>>> fibo(10)
55
>>> Math.abs(-1)
1.000000
}}}

=== コール演算子の省略}

コール演算子は、パラメータの数が１個であり、かつそれが文字リテラルである場合のみ、括弧()|自体を省略することもできます。次は、c.query("""...""")|と同じであるが、省略した方がすっきりとする。

{{{
>>> c.query """
select name, salary from PERSON_TBL
  where age > 45 and age < 65;
"""
}}}

== ビルトイン関数}

関数は、通常、プログラム実行時に評価されます。しかし、いくつかのプログラミング言語機能は、コンパイル時に評価しなければならなかったり、もしくは評価した方が効率がよい場合があります。Konoha では、これらのコンパイラと密接に結びついた機能をビルトイン関数として提供しています。

=== スタティックな型付け typeof()}

ビルトイン関数 typeof(expr)| は、プログラム中で、与えられた式exprのスタティックな型を調べるビルトイン関数です。

{{{
>>> a = 1
>>> typeof(a)
Int
>>> typeof("hello,world")
String
}}}

これに対し、(expr).class| は、実行時のexprがもつクラス（型）を調べるメソッドです。typeof(expr)とinstanceof の関係が成り立つが、必ずしも一致するとは限らない。また、型をもたないトークン（例えば予約語など)を評価した場合、void}型が返されます。

typeof()| 関数の評価は、コンパイラの型検査時に行われます。つまり、あまりおすすめではないが、次のように型名の代わりに型宣言にも利用できます。

{{{
int f(int n) {
   typeof(n) m = n + 1;
   return m;
}
}}}

=== 識別子の存在 defined()}

ビルトイン関数 defined(name)| は、識別子 nameが定義されているかどうか調べる関数です。

{{{
>>> defined(Class)
true
>>> defined(System.LINUX)
false
>>> defined(a)
false
>>> a = 1
>>> defined(a)
true
}}}

defined()| 関数の評価も、コンパイラの型検査時に行われ、必ず論理値 true} もしくはfalse} に置き換えられています。

{{{
if(!defined(System.LINUX)) {
   print os.uname;
}
}}}

=== デフォルト値をえる default()}

デフォルト関数default(expr)| は、プログラム中で、与えられた式exprの型からそのデフォルト値をえる関数です。

{{{
>>> default(String)
""
>>> default(%s(1))
""
>>> default(Script)                // Script は実行依存
main.Script
}}}

多くのデフォルト値は、スタティックに解決されます。しかし、いくつかのクラスは、実行コンテクストに依存する。そのため、デフォルト値も存在する。そのため、default()|はtypeof()|と同様にスタティックに型まで決定し、一部のデフォルト値は実行時に得ています。

=== デリゲートの生成 delegate()}

ビルトイン関数 delegate()| は、デリゲートクロージャを生成する関数です。デリゲートの詳細は、「第¥ref{sec:delegate}節 デリゲート」で述べます。

デリゲートdelegate(o, m)|は、閉包するオブジェクトo|と呼び出すメソッド名g|をセットにしてクロージャを生成する。

{{{
>>> String s = "name";
>>> f = delegate(s, split);
>>> f()                             // s.split() が呼ばれる
["n", "a", "m", "e"]
}}}

もしくは、delegate(f)|のように関数名f|のみを引数として与え、クロージャを生成することもできます。

{{{
>>> g = delegate(fibo);
>>> g(10)                           // Script.fibo(10) が呼ばれる
55
}}}

=== フォーマッティング format()}}

format()| は、「第¥ref{template_formatting}節 テンプレート・フォーマッティング」のとおり、テンプレート・フォーマッティングのためのビルトイン関数です。この関数がビルトイン関数である理由は、もし可能であれば、テンプレートのインライン展開を行い、フォーマッティングの性能を向上させるためです。

=== likely()}/unlikely()}*}

likely()|/unlikely()|は、論理値(true/false)を受け取り、その値をそのまま返すビルトイン関数です。ほとんどのプログラマには、この関数の存在意義からして疑わしいものかも知れないが、
Linux カーネル開発者など一部からは非常に好まれています。少なくとも、ソースコードが読みやすくなるという効果は認められるようです。

{{{
if(unlikely(a == b)) {
   // あまり起こらないケース
}
}}}

現在、Konohaでは、クラスルーム利用において、コンピュータアーキテクチャと結びつけて、プログラミングの深淵（の一部）を説明するときに役立つように導入しています。

将来、優れたKonohaコンパイラが登場したとき、likely()|/unlikely()|をひょっとしたら正しく解釈して、分岐予測の最適化を行ってくれるかも知れない。現在は、無害で副作用のないビルトイン関数であるが、もし使うのなら正しく使うことをオススメする。

%== クロージャ}
%== デリゲートクロージャ}
%== 無名関数}

¥chapter{クラスとオブジェクト}

%The object-oriented programming features in Konoha are mostly inspired by Java, nominal class and single-inheritance. Here is a running example in this section.

Konohaのオブジェクト指向プログラミングは、名前ベースのクラス(nominal class)、単一継承(single-inheritance)など、主にJava 言語のそれから影響を受けています。

== class 宣言}

新しいクラスは、class 文を用いて宣言することで定義できます。class 文の最も簡単なシンタックスは、次のとおりです。クラス継承を含めたシンタックスは、「第¥ref{class_inheritance}節 クラス継承」で扱う。

¥begin{quote}
class | $C$  {| ¥¥
  | $members$ // クラスのメンバー ¥¥
}| ¥¥
¥end{quote}

クラスのメンバーには、フィールド変数(field variable)、メソッド(method)、コンストラクタ(constructor)が含まれます。

¥begin{itemize}

¥item {¥bf フィールド変数}は、SmallTalk ではインスタンス変数、C++ではメンバ変数、Java ではフィールドとそろぞれ異なる呼称をもつが、オブジェクトの内部状態を表す変数です。Java ではフィールド変数と呼ばないのが正しいが、Konoha では変数の種類をその位置によって区別する統一呼称を用いているので、「フィールド変数」と呼んでいます。

¥item {¥bf メソッド}は、SmallTalkではメッセージ、C++ではメンバ関数とも呼ばれるが、オブジェクトの内部状態を操作する手続きです。メソッドは、関数のフォームをとり、パラメータ（メソッドにおける引数のこと）を受けて処理を行い、その結果を戻り値として返す。Konoha では、オブジェクトへの操作が明確なときはメソッド/パラメータ、そうでないときは手続き型言語風に関数/引数と呼び分けています。どちらも同じです。

¥item {¥bf コンストラクタ}は、新しくオブジェクトを生成するときに、new|演算子を用いて呼び出される特別なメソッドです。なお、Konoha は、ガベージコレクションの機構を備えているため、明示的なオブジェクト破壊を行う必要なない。

¥end{itemize}

さて、次はKonoha におけるクラス定義の例です。フィールド変数、コンストラクタ、メソッドの定義をもっています。フィールド変数は、class} ブロックの一番先頭で宣言することが（よみやすいため）一般的であるが、定義する順番は自由に変えても構いません。

{{{
class Person {
   String _name;                  // フィールド変数
   int age;
                                  // コンストラクタ
   Person(String name, int age) {
      _name = name;
      _age = age;
   }
   String getName () {           // メソッド
      return _name; 
   }
}
}}}

Konoha は、スクリプティング言語の柔軟さを提供するため、メソッドやコンストラクタを既存のクラスに追加するを認めています。しかし、フィールド変数のみは、class}ブロックであらかじめ定義しなければならない。

=== クラスの種類}

Konohaは、いくつかの特性の異なったクラスを分類しています。これらは、class 文} の前に、アノテーションを与えることで宣言することができます。

{{{
アノテーション         説明
@Private              名前空間からみることはできない。
@Final                これ以上、継承することはできない
@Singleton            Singleton 関数
@Interface            インターフェースとして利用することが可能
@Release              デバッグの完了したクラス
}}}

=== Glue}クラス}


== フィールド変数}

%The names of field variables should start with an underscore character. If you forget this rule (like age), the complier automatically adds _ to its name;

フィールド変数は、アンダースコア(_|)で始まる変数名をもつ。これは、Java プログラマがよく使っているローカル変数とフィールドを区別する慣習に由来するが、フィールド変数宣言のとき、アンダースコアを付け忘れなくても、コンパイラは自動的にフィールド変数にアンダースコアを付加する。

{{{
class Person {
   String _name;  
   int age;       // もし _ を付けなくても
   Person(String name, int age) {
      _name = name;
      _age = age;  // _ は、フィールド変数へのアクセスに必要
   }
}
}}}

%More importantly, the declaration of non-underscored field variables is shorthand for the automatic generation of its getter/setter. The compiler generates: 

重要な留意点は、フィールド変数宣言のとき、アンダースコアを付けないことは、自動的な getter/setter メソッドの生成を意味する。これは、次節で述べるとおり、フィールド変数の public 宣言に等しい。

{{{
class Person {
   ...
   int age;
   int getAge() { return _age;}           // 自動生成
   void setAge(int age) { _age = age; }   // 自動生成
}
}}}

%=== Field accessors}
=== フィールドアクセサ}

%In Konoha, all of field variables are private. You will have to access fields through getter/setter methods. 

Konohaは、全てのフィールド変数はいわゆる private} です。オブジェクト外部から直接参照はできず、全て getter/setter メソッドを用いて行う。

{{{
>>> p = new Person("naruto", 17);
>>> p.getName();
"naruto"
>>> p.setAge(18);
>>> p.getAge();
18
}}}

% This looks cumbersome. Konoha has the dot(.) operator for the shorthand of getter/setter. Using this, the above is same as:

フィールドへのアクセスに getter/setter メソッドを多用するのは、Java が産み出したトレンドです。しかし、これは何かと不便に感じる人も多い。そこで、Konohaは、フィールドアクセサ(.|演算子)を、getter/setter を呼び出すための省略形(シンタックスシュガー）として再利用しています。

{{{
>>> p = new Person("naruto", 17);
>>> p.name;                   // 実は p.getName()
"naruto"
>>> p.age = 18;               // 実は p.setAge(18)
>>> p.age;
18
}}}

今までどおり、フィールドアクセスをしているように見えて、実は全てgetter/setter メソッドによってふるまいを変更することができます。

=== バーチャルフィールド}

バーチャルフィールドとは、フィールド変数の実体がなくても、getter/setter を通して、あたかもフィールドが存在するようにふるまうことです。

{{{
class Person {
   ...
   String name;
   String getFirstName() { 
      return _name.split(" ")[0];
   }
}

>>> p = new Person("naruto uzumaki", 17);
>>> p.name                    // 実は p.getName()
"naruto uzumaki"
>>> p.firstName               // 実は p.getFirstName()
"naruto"
}}}

Konoha では、そのオブジェクトのクラスClass}インタフェースを通して、フィールド変数、（バーチャル）フィールドのリストを得ることができます。

{{{
>>> p = new Person("naruto", 17);
>>> p.class.fiedls("variable")
["_name", "_age"]
>>> p.class.fields("getter")
["name", "age", "firstName", "lastName"]
>>> p.class.fields("setter") 
["name", "age"]
}}}

=== this 参照}

キーワードthis|は、自オブジェクト参照への参照です。this|を用いたフィールドアクセサを用いると、フィールド変数を直接参照する代わりに、getter/setter を経由してアクセスすることになります。

{{{
   ...
   int age;
   boolean isDrinkable() {
      return (this.age => 20);
   }
}}}

フィールドアクセサによる特別な結果を期待する場合でもない限り、_age|で直接フィールド変数を参照した方が高速です。次のように、getter/setter メソッド内でthis参照を用いると、予期しない依存関係から無限ループに陥る危険性もあります。

{{{
   int _age;                        // やってはいけない
   int getAge() { return this.age;} 
   void setAge(int age) { this.age = age; } 
}}}

Konoha コンパイラは、getter/setter 内では、this 参照を使うとエラーになります。

== メソッド}

メソッドは、オブジェクトに対してメッセージを送受信する手段です。0個以上のパラメータを受け取り、0もしくは1つの戻り値を返すことができます。次の isChild()|は、0個のパラメータ、Boolean 型の戻り値をもったメソッドの例です。

{{{
class Person {
   String name;
   int age;
    ...
   boolean isChild () {
       return (_age < 21);
     }
}
}}}



=== メソッド追加}
Java 言語では、class 文の中でのみメソッドを定義することができました。Konoha では、動的言語の柔軟さを実現するため、既存のクラスに対して、スクリプト中どこでも新たなメソッドを追加定義することができます。次のPerso.isChild()関数は、class Person 内で定義されたisChild() と同じ定義になります。

{{{
boolean Person.isChild () {
   return (_age < 21);
}
}}}

メソッド追加は、これからインスタンス化されるオブジェクトのみでなく、（追加した時点で）既にインスタンス化されたオブジェクトにも影響が及びます。

{{{
>>> Person p = new Person("naruto", 17);
>>> boolean Person.isChild () {
...   return (_age < 21);
... }
>>> p.isChild()
true
}}}

=== 抽象メソッド}

抽象メソッドは、メソッドのインターフェースのみ定義され、実装パートが定義されていないメソッドです。Konohaでは、メソッドにつづくブロックが存在しなければ、抽象メソッドと解釈されます。また、メソッドのコンパイルに失敗したとき、自動的に抽象メソッドとして扱われます。

{{{
class Person {
   String name;
   int age;
    ...
   boolean hasFriend();           // 抽象メソッド
}
}}}

抽象メソッドの本来の用途は、抽象クラスやインターフェースなど、クラス設計においてポリモーフィズムを実現する手段としての利用です。厳密なスタティック言語では、全ての抽象クラスが実装されていない限り、クラスのインスタンス化はできない。しかし、Konoha は、抽象メソッドが含まれているクラスであっても、インスタンス化を認めています。これは、ラピッドプロトタイピングにおいて、単純に抽象メソッドを未実装なメソッドとして扱うためです。

抽象メソッドを実行すると、実行時例外となります。

{{{
>>> p = new Person("naruto", 17);
>>> p.hasFriend()
AbstractMethod!!: Person.hasFriend()
}}}

我々は、実行前にスタティックな抽象メソッドを検査する機構を検討しています。現在のところ、実行時にisAbstract()|によって検査する方法しかない。

{{{
>>> String.isAbstract()
false
>>> Person.isAbstarct()
true
}}}

=== パラメータの初期値}

メソッドの多重定義(overloding)は、異なる型のパラメータを同じ名前で定義することです。オブジェクトプログラミング言語の標準的な機能として、C++やJava言語で広く採用されているが、Konoha はメソッド再定義をサポートしていない。その代替機能として、パラメータの初期値を設定できます。

{{{
class {
   ...
   void Person.say(String msg="hello") {
      OUT << _name << " says " + msg << EOL;
   }
}
}}}

初期値が設定されたパラメータは、Nullable 型となります。したがって、パラメータを省略すると、自動的に null が与えられたものと解釈され、設定された初期値が渡されます。

{{{
>>> Person.says;
void main.Person.says(String? msg);
>>> p.say("aloha");
naruto says aloha
>>> p.say();　　                    // 省略, p.say(null) と同義
naruto says aloha
}}}

Konoha は、メソッドの多重定義をサポートしていない理由は、パラメータ初期値を活用することで、多くの場合のメソッド多重定義のバリエーションをカバーできるからです。あわせて、マップキャスト機能やAny}型パラメータを活用することで、いくつもメソッドを多重定義することなしに、同等なプログラミングが可能となります。

=== メソッドのバージョニング}

Konoha は、複数のメソッド実装をバージョン管理する機構を備えています。まず、メソッドのバージョニングは、オリジナルなメソッドに対し、パラメータの型と戻り値の型はそのまま同じで、メソッド名にバージョンタグ(:tag)を付けることで作成できます。

次は、:JA|タグを付加して定義したsays()メソッドの日本語版です。

{{{
void Person.says:JA(String msg = "こんにちは") {
   OUT << _naame << "は、"　<< msg << "と言った．" << EOL;
}
}}}

注意：（まだ厳密に決まった仕様ではないが、）英大文字で始まるタグは、言語ロケール用に予約されています。小文字で始まるタグは、ユーザが自由に利用して構いません。

バージョニングされたメソッドは、呼び出すときに明示的にバージョンタグを付けることで呼び出すことができます。

{{{
>>> p.says();
naruto says hello
>>> p.says:JA();　　                    // 日本語版の利用
naruto はこんにちはと言った.
}}}

¥subsubsection{将来の拡張計画}

将来のKonohaでは、型による自動的なバージョン切り換えも導入を予定しています。この機構には、セマンティックプログラミングの意味タグ型を流用する予定であるが、セマンティックプログラミングとの一貫性に関して検討を必要としています。

次は、Person}クラスに対し、意味タグを追加して、意味タグ型 Person:JA}型の例です。意味タグ型は、同じタグが付けられたメソッドを優先して呼び出す出されることになります。

{{{
>>> Person:JA p = new Person("なると", 17);
>>> p.says();                           // says:JA()を利用する
naruto はこんにちはと言った.
}}}

== クラス関数}
¥index{くらすかんすう@クラス関数}
¥label{class_function}

クラス関数は、クラス名を直接レシーバにして利用できる特別なメソッドです。通常、メソッドは、クラスのオブジェクトを操作するための手段です。したがって、メソッドを利用するとき、クラスがインスタンス化されている必要があります。しかし、特定のインスタンスから独立しており、インスタンスを特定できない、もしくはする必要がない場合があります。


乱数生成メソッド random()|は、特定の数値（インスタンス）の操作というより、それに独立したユーティリティ機能となります。ただし、Int} や Float} クラス程度に操作を区別する必要もあります。Konoha では、これらは、クラス関数としてそれぞれ定義されて提供されています。

{{{
>>> Int.random()
143980198322
>>> Float.random()
0.39810
}}}

クラス関数は、メソッド定義のとき、@Static| アノテーションを付けることで定義することができます。

{{{
@Static
int Int.max(int a, int b) {
   return (a > b) ? : a : b;
}
}}}

@Static|アノテーションは、Java のスタティックメソッド¥index{すたてぃっくめそっど@スタティックメソッド}に由来しています。事実、見かけ上、クラス関数はスタティックメソッドと同様に利用することができます。しかし、実際はクラスのデフォルト値をレシーバとしてメソッドを呼んでいます。this} キーワードを用いれば、自オブジェクトとして参照もできます。

{{{
>>> Int.max(1, 2)
2
>>> (default(Int)).max(1, 2)     // 同じ
2
}}}

また、シングルトンクラスは、@Static|アノテーションがなくても、自動的にクラス関数として解釈されます。そのため、クラス関数としてコールしてもよいし、メソッドとしてコールしても構いません。

{{{
>>> System.exit()                // System はシングルトン
>>> os = default(System)
>>> os.exit()                    // 同じ
}}}

Konoha は、シンプルな言語構造を実現するため、Java風のスタティックフィールドをサポートしていない。クラスで共有したい変数は、単にスクリプト変数を用いることができます。

== コンストラクタ}


== オペレータとメソッド}

Konohaでは、全てのオペレータはメソッドのシンタックスシュガーです。例えば、加算演算 x + y| は、次のように単純にメソッドopAdd()|に置き換えられて実行されています。

{{{
x.opAdd(y)                            // x + y
}}}

そこで、演算子と対応つけられたop| で始まるメソッドを定義すれば、オペレータの振る舞いを変更することも可能です。ただし、演算子の再定義は、Konohaではあまり積極的に推奨されない。

¥begin{tabular}{llll}
x + y| & x.opAdd(y)| & x - y| & x.opSub(y)| ¥¥
x * y| & x.opMul(y)| & x / y| & x.opDiv(y)| ¥¥
x mod y| & x.opMod(y)| & & ¥¥
¥verb/x++/ & x = x.opNext()| & ¥verb/x--/ & x = x.opPerv()| ¥¥

x == y| & x.opEq(y)| & x != y| & x.opNeq(y)| ¥¥
x < y| & x.opLt(y)| & x <= y| & x.opLte(y)| ¥¥
x > y| & x.opEq(y)| & x >= y| & x.opNeq(y)| ¥¥

x & y| & x.opLand(y)| & ¥verb/x | y/ & x.opLor(y)| ¥¥
x ^ y| & x.opXor(y)| & ‾x| & x.opLnot(y)| ¥¥

x << y| & x.opLshift(y)| & x >> y| & x.opRshift(y)| ¥¥
¥verb/|x|/ & x.getSize()| & ¥verb/y in? x/ & x.opHas(y)| ¥¥

x[n]| & x.get(n)| & x[n] = y| & x.set(n)| ¥¥
x[] = y| & x.setAll(n)| & x[s..e]| & x.opSubsete(s,e)| ¥¥
x[s..<e]| & x.opSubset(s,e)| & x[s..+n]| & x.opOffset(s,n)| ¥¥
¥end{tabular}

¥begin{comment}
== フォーマッタの定義}

=== フォーマッタメソッド}

You can define or add new formatters as methods, since formatters are a specialized method with the following signature.

{{{
void Object.%fmt(OutputStream w, String fmt) ;
}}}

Formatting is designed to output data to OutputStream. 

{{{
void Person.%xml(OutputStream w, String fmt) {
   w << "<person name='%s{0}'/>" %% _name << EOL;
}
}}}

{{{
>>> p = new Person("naruto", 17);
>>> %xml(p)
<person name='naruto'/>
}}}

== マッパーの定義}
¥end{comment}

¥chapter{クラス継承と抽象化}

クラス継承(class inheritance)は、オブジェクト指向プログラミング黎明期の一大関心事であった。しかし、オブジェクト指向プログラミングが広く普及し、多種多様なオブジェクトのデザインパターンが実践されるにつれ、それほど関心を集める話でなくなった。

Konoha は、そんな時代に設計されたので、「クラス継承」に関して、必要最小限の機能をサポートするのみにとどめています。（しかも、現在のところ、ほとんどクラス継承を使う機会はない。）

== クラス継承} ¥label{class_inheritance}

Konoha のオブジェクト指向プログラミングは、Javaから強い影響を受けています。クラス継承を用いるクラス定義は、Java同様、 class文においてextends} 節によって上位クラス$D$を指定することができます。クラス継承によって定義されたクラス$D$は、上位クラス$C$に対し、「サブクラス(subclass)」と呼ぶ。

¥begin{quote}
class | $D$  extends | $C$  {| ¥¥
  | $members$ // クラスのメンバー ¥¥
}| ¥¥Konoha は、Javaのオブジェクト指向プログラミングの特徴を強く受け継いで設計されています。
¥end{quote}

クラス継承とは、上位クラスの振る舞い、つまりメソッドを引き継ぐことです。サブクラスでは、上位クラスのメソッドを継承するのみならず、新たなメソッドを追加することもできます。次のクラスD}は、クラスC}のサブクラスです。メソッドC.sayHi()|を継承し、新たにD.sayBye()|を追加しています。

{{{
>>> class C {
...    void sayHi() { print "hi"; }
... }

>>> class D extends C {
...    void sayBye() { print "bye"; }
... }

>>> D d = new D();
>>> d.sayHi()           // c.sayHi()が呼ばれる
hi
>>> d.sayBye()          // 追加されたメソッド 
bye
}}}

=== final} クラス}

Konoha では、クラス定義において、Java 言語同様、final}修飾子、もしくは@Final}アノテーションを付けることで、クラス継承不可能なクラスとして宣言できます。

{{{
final class C {
   void sayHi() { print "hi"; }
}

class D extends C {    // C は継承できない
   void sayBye() { print "bye"; }
}

}}}

== オーバーライド}

オーバーライドは、継承されたメソッドをサブクラスにおいて上書き、つまり新たに作り直す機構です。オブジェクトに対しポリモーフィズム(polymorphism)を与える重要な機構であるが、同時に、ダイナミックバインディングによる性能低下が議論となる機構でもあります。

Konoha は、C++ や C¥#の流儀にしたがって、@Virtual}アノテーションが付けられたメソッドのみオーバライドすることができます。これは、実際のプログラミングにおいて、メソッドがオーバーライドされることは稀であり、Java のようにデフォルトでオーバーライドを認めることによる性能ロスを無視できないと判断したためです。プログラマがダイナミックバインディングを避けるためfinal}を追加するようなテクニックを駆使することなく、ふつうに書いて最適な速度が得られる方を好んだといえる。

{{{
class C {
   @Virtual void sayHi() { print "hi"; }
}

class D extends C {    
   // オーバライド
   @Override void sayHi() { print "Hey"; }
   void sayBye() { print "bye"; }
}
}}}

注意： @Virtaul} メソッドは、ダイナミックバインディングされるため、どうしてもスタティックバインディングに比べると遅くなります。Konoha では、インラインキャッシュによる高速化の工夫をしているが、オーバーライドする必要のないメソッドは@Virtual 宣言しないようにすべきです。また、抽象メソッドもオーバーライドされたメソッドも、同様に、ダイナミックバインドされます。

=== ポリモーフィズム}

== super}}

{ｴsf super} は、上位クラスのフィールドやメソッドへアクセスするためのリファレンスを表す表現です。

== インターフェース*}

Konoha は、Javaと同様に、単一継承(single inheritance)です。複数のクラスの振る舞いを継承するクラスを定義したいときは、インターフェースを実装する方法を用います。次は、クラス$D$とクラス$E$のインターフェースを実装することを宣言したクラスです。

¥begin{quote}
class | $C$  implements | $D$, $E$  {| ¥¥
  | $members$ // クラスのメンバー ¥¥
}| ¥¥
¥end{quote}

Konoha は、Java と異なり、インターフェースを定義する専用のinterface} 文は存在しない。その代わり、任意のクラスをインターフェースとして実装することができます。

{{{
>>> class C {
...    void sayHi() { print "hi"; }
...    void sayBye() { print "bye"; }
... }

>>> class D implements C {
...    void sayHi() { print "Hai"; }
... }
>>> D d = new D();
>>> d.sayHi()                      // 自分で作る
Hai
>>> d.sayBye()                     // 継承されない
 ** AbstractMethod!!
}}}

注意: インターフェースは、あくまでもメソッドの設計（シグネチャ）のみ継承し、実装は継承しない。Konoha では、抽象メソッドとして継承されます。そのため、新たに追加しない限り、implements} されたインターフェースのメソッドは、Abstract!!|例外になります。

=== インターフェースへのメソッド追加**}



== Object} クラス}

Object} クラスは、全てのクラスの共通した上位クラスです。全てのオブジェクトは、Object}クラスのメソッド（オペレータ、フォーマッタも含む）を継承しています。

