プログラミング言語過去問回答
2010年度プログラム言語の回答です。多分間違いがあるので見つけたら教えてください。
Java言語が前提、C++とかだと挙動が違う。(JavaはC++でいうvirtualがすべてのメソッドにデフォルトでついてる)
サンプルコードは、授業で出て来なかったような記法はなるべく避けてます
オーバーライドとオーバーロード
名前が似てるだけで、機能は全然別の物。
オーバーライドとはポリモーフィズムにおける機能で、継承を行っているクラスが基底クラスの同じシグネチャ(メッソド名、引数リストの型、戻り値の型)を持つメソッドを上書きするもの。
import java.util.*; public class SomeApplication{ public static void main(String[] args){ new SomeApplication().sample(); } public void sample(){ // Human型で宣言するので、それを継承するクラスなら入れられるのが味噌 ArrayList<Human> people = new ArrayList<Human>(); people.add(new Japanese("太郎")); people.add(new English("Watson")); for(Human h : people){ // hがJapaneseの時と、Englishの時で挙動が変わる // これはgreetメソッドをオーバーライドしているので起こる // たしかにHuman型のhだが、数行上を見ればわかるように、実際は // EnglishとJapaneseが入ってて、同じコードでも別の挙動をする。 h.greet(); } } public class Human { String name; // 実際は抽象クラスと抽象メソッドを使うべきだが、 // まぁこまけぇことはいいんだよ!! public void greet(){} } public class English extends Human { // コンストラクタ。これも本当は・・・こまけぇことはいいんだよ!! public English(String name){ this.name = name; } // ここで実際にオーバーライド // 英語圏の人の場合の挙動 public void greet(){ System.out.println("Hello! I'm " + name + "."); } } public class Japanese extends Human { public Japanese(String name){ this.name = name; } // 日本語圏の人の場合の挙動 public void greet(){ System.out.println("こんにちは!! 私は" + name + "です"); } } }
結果:
こんにちは!! 私は太郎です Hello! I'm Watson.
オーバーロードとは、同名でもメソッドシグネチャの違いによって適当なメソッドが自動で選択される物。
//インスタンス作るのがめんどくさいので全部static public class SomeApp2 { public static void main(String[] args){ // 同名のメソッドを呼び出しても、引数、戻り値の型を考慮して // 自動的に呼び出すメソッドを選定してくれる SomeApp2.hoge(1); // 2が呼ばれる SomeApp2.hoge("foo"); // 1が呼ばれる } // 1 public static void hoge(String s){ System.out.println("String"); } // 2 public static void hoge(int i){ System.out.println("int"); } }
結果:
int String
Appletにおけるアニメーション概要
Threadクラスを使って、メインスレッド以外のスレッドから定期的にコンテクストを書き換えることでアニメーションを実行する。
例えば、四角形を横に動かすプログラムの場合
- AppletにRunnableを実装する
- Runnable.runをオーバーライドして、そのなかでwhile(true){四角形位置更新→repaint→スリープ}処理をする。
- initメソッドの中でnew Thread(this).start()をする。
もうちょっと長い説明にすべきですかねぇ。 学校のページを参照してください。
primeFactor
void primeFactor(int n){ for(int i = 2; i <= n; i++){ if(n % i == 0){ System.out.printf("%d ", i); n /= i; i = 1; } } }
本当は良くないんですが、仮引数のnをどんどん割っていって出力してます。
一つ因数を見つけたら、また2から辿ります。
fib
int fib(int n){ if(n < 2){ return n; }else{ return fib(n - 1) + fib(n - 2); } }
という定義を考えれば、割と自然なのでは。
Range
a: "upper - lower + 1"
b: "i + lower"
まんまですね。