OCJ-Pの反省
去年落ちたわけだけど、なぜか。
それは丸暗記しようとしていたから。
継承関係の制約とか、どういう意図を持って言語仕様が定められているのか、
理解していないと、ちょっとの例外ケースでわからなくなるし、実務で役に立たないよね。
つまりは落ちたのは、そういうことだ。
決めた
はじめに
突然だが、僕は文鳥が好きだ。
好きすぎてたまらない。
離れてると、文鳥たちが今何をしているか、寒くないか、暑くないか、
腹をすかせていないか、水切れを起こしていないか、
水浴び用の水は足りているか、
気になって仕方がない。
なので、文鳥が今何をしているか、見守ることができる装置を作ることにした。
なにをしたいか(どうやって実現するか)
文鳥の活動を検出する
Arduinoを使って、位置センサを接続。
かごの中にいる文鳥の動きを軌跡として表示する。
赤外線距離センサーとエクセルVBAを用いた物体、生体の運動記録。ArduinoとエクセルVBAの通信
またはRaspberryPiに位置センサをつなぐ
Raspberry Pi で測距センサ GP2Y0E03 を使う: technology memo
Raspberry-Piに距離測定モジュールを接続 - YouTube
リアルタイムにわかるのはもちろん、1時間の累計、1日の累計なんかも見れるといいね。
文鳥動画をストリーミング配信する
Webカメラでストリーミング配信する。接続すると、LED照明がつく。
文鳥に水をやる
Webでクリックすると、給水器底部の栓が抜け、古い水が下のタンクに流れ込む。
代わりに上部の水タンクから新しい水が来る。(市販のペット自動給水器なんかを参考)
フェールセーフとして、旧来の水飲み器も残しておく。
文鳥に餌をやる
Webでクリックすると、ブロワーで古い餌を吹き飛ばし、新しい餌が流れこむ。
フェールセーフとして、旧来の餌も残しておく。
追記:新しい餌の流れ込み部分は、この形式が役に立ちそう。
David Bryan's Blog | Raspberry Pi Power Cat Feeder – Updates
文鳥の機嫌がわかる
文鳥の声から、出たがってるか、唄ってるか、喧嘩をしているかを判別する。
まず何からするか
文鳥動画をストリーミング配信からやるのがよさそう。Webアプリの知識が必要
測距センサの実装は楽しそう。組み込みデバイスの知識が必要
機嫌センサは機械学習とか音声認識の知識が必要
無謀そうだけど、1つづつ分解してやっていけばきっと出来るはず!
そのうちGitHubに公開します。
GitHub アカウントの作成方法: ある SE のつぶやき
OCJ-P対策
クラスの継承関係あたりをメモ。
package sun.text; public class InheritanceExercise { String salute = "Hello"; public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); E e = new E(); // コンパイル時にわかる継承関係に無いクラスはエラーになる // System.out.println(a instanceof B); System.out.println(c instanceof B); System.out.println(e instanceof D); // staticメソッドから、インスタンス変数にアクセスできない // System.out.println("Salute :" + salute); // インスタンスを作ってからアクセスすれば可 System.out.println("Salute :" + new InheritanceExercise().salute); } } /* * 継承関係にあるクラスの判定 */ class A { } class B { } class C extends B { } /* * インターフェースの実装の練習 */ interface D { // int a; // 変数は、暗黙的にpublic static final(これだけが許可) // abstract int a = 0; int a = 0; // メソッドは、暗黙的にpublic abstract(これだけが許可) // メソッド定義{}を書くとエラーになる // void A(){}; void A(); } class E implements D { // final変数になるので、値の変更はできない // a = 2; int b = a; // interfaceはpublicなので 可視性を下げることはできない // protected void A(){} public void A() { } } /* * 同じメソッド名、変数をもつインターフェースを継承したケース */ // インターフェースはインターフェースを継承できる interface D2 extends D { int a = 1; void A(); } class E2 implements D, D2 { // インターフェース変数は、重複はだめ。 // static変数なので、<インターフェース名>.変数名 // int b = a; int b = D2.a; // メソッドは重複OK!なぜなら、空実装だから。 @Override public void A() { } } /* * 抽象クラスの実装の練習 */ abstract class F { // 抽象メソッドでなければ、メソッド定義{}を書かないとエラーになる // void A(); // 抽象メソッドでなければ、実装クラスに実装を強制しない void A() { } // 逆に、抽象メソッドではメソッド定義を書くとエラー。 // 最後にセミコロンが必要! abstract protected void B(); } class G extends F { @Override // protectedより厳しくできない // void B() { public void B() { } }