読者です 読者をやめる 読者になる 読者になる

NEGAKULIFE

ネ学生のQoLを上げるブログ

ネ学生のQoLを上げるブログ

課題が終わらないのは仕様

インターンでQoLをガリガリ上げる話

1年向け 2年以降向け ネ学

お久しぶりです。先日はEDPSの合宿お疲れ様でした。めちゃくちゃ楽しかったです。楽しかった。

合宿にもお金がかかります。僕も金欠です。
大学生活にはお金がかかります。
バイトもせずに過ごすクソニー石油王な方々もいるそうですが、ほとんどの人はバイトをして、自分の活動費を賄っているのでは無いでしょうか?

ネ学来てバイトすんの?

僕は、入学時から一年ちょい、塾のバイトをしていました。塾のバイトのクソさは語り始めると長くなるので割愛します。
(去年の夏期講習は週6で働いて18万くらい稼ぎました)

辞めた理由は多々ありますが、一番大きいのは「こんなパンピーみたいなことしてられっか」という点です。
昨今の日本は、IT技術者が不足している状況にあります。国も困っています。そこで僕らのいる学部を思い出してください。

インターネット情報学部」

わざわざたっけー金払ってインターネットで情報な学部にいるのに、クソ親の文句を受けつつクソガキの相手をするのってあほらしくないですか?
わざわざたっけー金払ってインターネットで情報な学部にいるのに、低賃金で牛丼盛るのってあほらしくないですか?

別にその職業を貶している訳ではありません。ただ「僕らには他人とは違う知見がある」という一点に尽きます。 上記で示した職業は一例です。正直言って誰でも出来ます。誰でも出来ることを誰でも貰えるようなお給料でこなして時間を浪費するのをやめませんか?って話を今回します。少なくとも興味のある人も居ると思うので、そういう人にもタメになるようなことを書こうと思いましたが無理でした。

インターンってなんだ

僕もよくわかりませんが、大別すると二種類あるようです。

  • 企業にすり寄って媚を売り勉強するタイプ
  • 企業にすり寄って時間か技術を売るタイプ

前者の媚を売るタイプは、就活前の方々がよくやられているように感じます。他学部の先輩などに散見されます。場合によりますが、基本お給料は出ないようです。勉強しに行ってるんですからまぁ当然です。

後者の時間か技術を売るタイプは「長期インターン」とも言われるようです。アルバイトと大差ないように感じます。なんでインターンっていうんでしょうか。
僕らが目指すべきは後者です。前者は大学生活をなんとなく過ごしてきたクソザコナメクジがやってればいいんです。と、言うただの暴言も正当な理由があります。後ほど。

僕のインターン

インターンを決めるまで

塾をやめ、インターンを探しました。色んなインターンサイトがあります。これに限っては色々試してみるしかないようです。場合によっては1週間以上音沙汰が無いクソみたいなサービスもあるので、気長に行きましょう。

最初は「オフィス見学しに来ませんか?」というメールを頂いたので、とりあえず履歴書を拵えてオフィスへ。担当の人と面接というよりも、日常会話のような会話を行いました。僕の場合はMinecraftでの活動をめちゃくちゃ喋ったりして、色々な展望をお互い(!?)語り合いました。そこで相手方から「来週から来てって言ったら来れる?」と。

ぼく「週7で行くのも吝かでないです」

そして僕のインターン探しは終わりました。

インターン入った後

僕の入った企業は、従業員10人いるかいないかの小さいベンチャー企業で、実績もそこそこあり、現在はiPhoneアプリを作っている所でした。
いい感じのアプリを作っているため、デザインが要される為、デザインのインターン生が5人ちょい居ました。

ここで驚きなのが、エンジニアが僕含めて4人しか居ないという所です。企業にとってのエンジニアの需給が伺えます。

僕の場合は、1週間でRuby on rails(これは二年次NSの後期でやります)を覚えてって言われたので、言われたとおりのチュートリアルを3日で撃滅。4日目からAPI方面のインフラをちょいちょい手伝うことになりました。割と得意だったので「即戦力すぎて怖い」って言われたのはそこそこ嬉しかったです。

オフィスは表参道にあり、マンションのワンフロアをぶちぬいたような所です。ランチとか超オシャンティーで息苦しいです。あと高い。
社長も若くて気さくで、よくご飯をごちそうしてくれます。EDPS合宿後に会社の旅行で箱根に行ったのですが、諸々全部出して頂きました。高級旅館なんて初めてです。

エンジニアが少ないこともあり、すぐ社員の人とも打ち解けられました。ベンチャー企業なので、夢を語る機会が大きく、色んな知見を得られます。昨今の企業の動向とか、エンジニアの異動とか、お金の話とか、色々です。

あれ?

ここまである程度読んで頂けたらお気づきだと思います。先ほどインターンは大別して二種類あると言いましたが、後者は前者を内包しています。
「お金も貰えて、技術も学べて、知見を得られて、企業と繋がりが出来る夢のお仕事」。学生の特権です。

インターンをしよう

インターンはとても良い機会です。ネ学の皆さんは是非行くべきです。

ただ、ここで「私には技術なんて無いし~」とか言うクソザコナメクジが現れます。それは甘えです。

甘えというのも過言ですが、奴らが求めているのは「情報系にそこそこ知見のある人」に尽きます。つまり、技術とか経験とかは心底どうでもいいんです。そこは企業サイドがカバーすべき項目であって、僕らが気にするべき所で無いし、技術がそこそこあるならそれこそ就職すべきです。

めっっっっっっっちゃ気楽に行きましょう。僕は「後期のNSでやる項目カバーしつつ金貰えるなんて神かよ」って気分で最初入りました。

面接みたいな場では「こういうことをしてきました(学んできました)。よくわからんけどこういうことしたいです。教えてくださいペロペロ」みたいな感じで行きましょう。着飾る必要なんて一切無いです。

まとめ

  • 長期インターンをしよう
  • 決まるまでは割と長い
  • 規模の小さい会社にいこう
  • 箱根は素晴らしいぞ
  • うちの猫はニャンタマが取られましたが元気です

SD攻略決死隊 - 水泡と化す過去の軌跡 後編

2年以降向け SD/NS ネ学

こんにちは、夕飯を食べ終わりました。
それにしても今週忙しすぎないですか?

前編では、チャットクライアントとかそういう話しました。後編はプログラミングの話です。 「途中で動かなくなった」とか言っている人向けかもしれないです。

ソースコードがきたねえ

僕も余り人のことは言えないんですが、これに尽きます。「色々課題にそって追加してったら動かなくなった」っていう人のソースコードを診ると、ゴチャゴチャでよくわからないことになっています。C言語でも書いてるのか????ってツッコミたくなります。そこまでは行かずとも「関数・メソッド」という括りを上手く使いこなせれば、もっとより良いコードが書けるのではないかと思います。(あくまで個人的感想で、ここは結構ナイーブな問題なので宗派が違うひとはすいません)

例えば、以下のような、サーバーサイドのプログラムがあったとします。

@Override
public void run() {
    try {
        out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String fromClient;
        while((fromClient = in.readLine()) != null) {
            System.out.println(fromClient);
            if(text.startsWith("user")) {
                String[] args = text.split(" ");
                if(args.length == 4 && args[2].equals("pass")) {
                    if(checkId(args[1], args[3])) {
                        //ログインしたらそのクライアントを通す
                        out.println("0 login succeed");
                        userName = args[1];
                        //ユーザーがログインしたことを全員に知らせる
                        for(ChatMThread client: member) {
                            client.out.println("login" + userName);
                        }
                    } else {
                        out.println("100 password invalid");
                        end();
                    }
                }
            } else if(text.startsWith("chat")) {
                //あといろいろ処理
            }
        }
    } catch(IOException e) {
        end();
    }
}

読めはする

なんとなく意味はわかります。サーバー側のin(前回参照)から受け取った文字列をスペースで分割して、一つ目が「login」だったらログインをする処理です。一見良いように見えますが、これに処理を加えていってしまうと、どんどんコードが肥大化してしまいます。あなたのコードもそうなっていませんか?

改善していく

プログラミングは「人類が楽をするため」に存在します(えしら談)。何度も同じことを書くような「めんどくさい」ことをするのって本末転倒じゃないですか?

また、同じ処理を色んな所に何回も書くのは、効率が悪いだけではなく、メンテナンスがしづらくなります。「後から見返してよくわからない」「一発で自分の書いた処理がどこにあるのかがわからない」のはこれが原因です。

細かくちぎっては投げ

なので、処理を全部わけちゃいましょう。

最初に目をつけるのは、クライアントにメッセージを投げる部分です。「out.println」とか「client.out.println」とか、上のログイン処理だけでも3回も出てきてますよね?これを全部分けてしまいます。しかし一様に「クライアントにメッセージを投げる」といっても、二種類存在する事にお気づきでしょうか。

「一つのクライアントにメッセージを投げる」のと「全てのクライアントにメッセージを投げる」の二種類があります。これを前提にこんな改善を行ってみます。

@Override
public void run() {
    try {
        out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String fromClient;
        while((fromClient = in.readLine()) != null) {
            System.out.println(fromClient);
            if(text.startsWith("user")) {
                String[] args = text.split(" ");
                if(args.length == 4 && args[2].equals("pass")) {
                    if(checkId(args[1], args[3])) {
                        //ログインしたらそのクライアントを通す
                        send("0 login succeed");
                        userName = args[1];
                        //ユーザーがログインしたことを全員に知らせる
                        sendAll("login" + userName);
                    } else {
                        send("100 password invalid");
                        end();
                    }
                }
            } else if(text.startsWith("chat")) {
                //あといろいろ処理
            }
        }
    } catch(IOException e) {
        end();
    }
}

public void send(String msg) {
    out.println(msg);
}

public void sendAll(String msg) {
    for(ChatMThread client: member) {
        client.out.println(msg);
    }
}

送る部分を分けてみました。結果的なコードは長くなっていますが、「どこで何をやっているのか」が明確になりました。ここで、更に一工夫加えてみましょう。sendAllは「全てのクライアントにメッセージを投げる」ものですが、中身を見ると「全てのクライアントに順番に見て、一つのクライアントにメッセージを投げる」ということをしています。これを考えると、以下のように書き換えることも出来ます。

public void send(String msg) {
    out.println(msg);
}

public void sendAll(String msg) {
    for(ChatMThread client: member) {
        client.send(msg);
    }
}

こうすると、全ての「メッセージを投げる」処理が最終的に「sendメソッド」に集約されることになります。これには様々なメリットがあると思います。

例えば、何かの都合で(まぁこの課題ではありえませんが)、「クライアントに送る方法がout.println()からout.message()に変わったから!」と仕様が変わったとします。そういう場合に最初のコードだとどうでしょう。三箇所も書き換えなければいけません。処理が増えていた場合は、もっと多くの箇所を修正する必要があります。次のコードだと、二箇所の変更で済みます。最後のコードだと、一箇所で済みます。これって凄い大きいことじゃないですか?!

分割するセンス

かといって、正直いってどこまで分割していくかというのは好みの問題です。「細かすぎるとみづれえ死ね!」っていう人もいれば「細ければ細かいほど良い(世の中にはメソッドは1インデントで納めろという人もいるとか…)」という人もいます。

結果的に動けばどうでもいいです。ただ自分の書いたコードを後から見返して苦痛なのは嫌だよね!

まとめ

  • 今回のSDは爆死者続出
  • ほんとにソース理解できてる?
  • スパゲッティコードは殺せ
  • 分割はセンス
  • ちなみに僕は「あ、この処理さっき見たな」ってなったら分割してます
  • 「作り直しの美学」
  • 猫はすくすく育ってるよ

SD攻略決死隊 - 水泡と化す過去の軌跡 前編

2年以降向け SD/NS ネ学

こんにちは。お久しぶりです。
今回はSDの最終課題についての話をします。

ヤバい人が多い

SDの最終課題である「チャットクライアント」ですが爆死者が続出しています。
前回(2016/07/07)では、定時に帰れる人はほとんど居ませんでした。
それに対して、自分は定時より前にタスクを終えることが出来ました(自慢では無いよ!)

今回は、「なぜ自分は早く終われたのか」という所を自己分析しつつ、プログラミングをしていく時に「このように考えるとスムーズなのでは?」という点を 考えて示していけたらと思います。
直接的な問題に対する答えを示す訳ではないので、ご留意ください。

爆死原因を考える

爆死した人を見てみると、様々な原因が考えられます。

  • プログラムの構造を理解出来ていない
  • 色々なWebなどを参考にしすぎてヤバい
  • 追加したプログラムがゴチャゴチャで整理できていない
  • ロジックがヤバい

一方、Javaの書き方には流石に慣れてきており、そこはあまりネックになっていないように感じます。(ここが大事で、Javaの書き方すら怪しい人はマジでヤバいです。)

一貫して言える事は「その書いてるプログラム、ほんとに理解できてんの?」っていうのが根底にあると思います。
ここでの理解とは、「読むことができ、やってることを他人に説明できる」までを含みます。結構大切だと思います。

プログラムの構造を理解する

チャットクライアントの動作を追ってみる

SD最終課題は、ステップバイステップで進んできています。 つまり、出発点は皆一緒で、教科書に載ってる「カウンセラーとのお話をするプログラム」を改造していく課題であるとも言える訳です。 この段階で、「やべえ、チャットクライアントいきなり作れって言われてもわかんねえ、ググるか」って言ってる人はすぐ死にます。

対話?チャット?どう動いてる?

最初は、対話プログラムの動作を理解する必要があります。教科書と課題の順を追って理解してみましょう。

最初は、教科書16.3までです。これは「サーバー」と「クライアント」が一対一で対話を行います。図示すると以下のようになります。

f:id:ne5oku:20160710184307p:plain それぞれサーバーとクライアントには、出口と入り口(outとin)があります。例えば、クライアントからサーバーに情報を送りたかったら、クライアント側の出口(out)に情報を渡して上げます。そうすると、不思議なことにサーバー側の入り口(in)に情報が流れ着きます。逆も然りです。これが今回の課題の超大切な部分です。

しかし、これだと一対一で不便だよね!って事で次が教科書16.4です。スレッドってのを使うことで、複数のクライアントとの接続を可能にします。図示すると以下のようになります。 f:id:ne5oku:20160710184817p:plain 先ほど、出口と入り口を持っていたサーバーですが、今回は出口も入り口も持ちません。サーバーは、クライアントが接続してきたら、それぞれのクライアントとの通信を行う部分(つまり、出口と入り口)を持つ「スレッド」をぬるっと作り出し、それに情報のやりとりをさせます。サーバー一人だと大変だから、自分の分身みたいのをもりもり作って、そいつらに仕事をさせてるような感じです

鋭い人はここで気付くと思います。対話プログラムもチャットプログラムも、本質的にやってる事は変わらない訳です。

短くなりましたが、前編はここまでで。中編だか後編だかは、夜ご飯を食べた後に上げたいと思います。

ShareXで画面キャプチャしてQoL爆上げ

1年向け 2年以降向け QoL爆上げ ネ学

お久しぶりです。ブログなんてありましたね。
様々な記事の切れ端みたいのが下書きにたまっていてしょうがないので、適当な短文形式で色々書いていきます。(今までが長すぎた)

スクリーンショットってどう撮ります?

スクリーンショット、スクリーンキャプチャ、スクリーンダンプとは、コンピュータのモニタもしくはその他の視覚出力デバイス上に表示されたものの全体または一部分を写した画像のこと。略して、スクショとも呼ばれる。(Wikipediaより)

皆さんもレポートなどを書く際、Twitterに画像を載せる際にスクショを撮るのではないでしょうか?

では、そのスクショ、どうやって撮ります?

Windowsなら、Print Screenボタン。MacならControl+Command+3で全画面、Control+Command+4で選択範囲、Control+Command+4+Spaceでアクティブウィンドウを写真に収めることが出来ます。
(Macのほうが便利ですね!)

他にも、Gyazoを使って、自動でアップロードしてくれるサービスなどもあります。

ShareXとは

ShareXは、画面内の好きな部位や、ウィンドウ単位、画面全体などを「画像ファイル」として保存しておくことが出来ます。 公式Webサイト f:id:ne5oku:20160628011136p:plain

まとめ

  • ブログは大変

ゼネコンミニプロの宣伝と自己紹介

1年向け 2年以降向け ネ学

こんにちは、お久しぶりです。最近は猫と睡眠が捗って仕方が無いです。
今回は、先週の金曜日(2016/6/3)に行われた、ミニプロ「ゼネコン」の企画である「ガバガバ発表会」についての話をします。

ミニプロとは?

某サークルが独自で行っている、プロジェクト活動の縮小版みたいなヤツです。様々なプロジェクトが起案され、活動しているらしいです。

ゼネコンとは?

ミニプロの企画の一つで「ゼネがコンな人材を育成しよう(要加筆修正)」という感じのミニプロです。水曜日の4限と、金曜日の昼休みに活動しています。
成果物を出すタイプのではなく、人が集まって色々話をして知識を深めようというタイプのミニプロとなっていますので、サークル外の人でも誰でも参加することが(理論上)できます。

ガバガバ発表会

水曜日の4限と、金曜日の昼休みのゼネコンは、厳密には区別されています。水曜日の方は、主に講義形式のトークを行っており、金曜日の方は、LT*1という形式で行われています。

初回で僕が行った内容と方向性

僕は個人的に「Minecraft」というゲームをぶちあげマックスで布教したいと思っています。
そのための布石が初回の発表でした。

実際の発表

f:id:ne5oku:20160605023322p:plain f:id:ne5oku:20160605023328p:plain f:id:ne5oku:20160605023331p:plain f:id:ne5oku:20160605023333p:plain f:id:ne5oku:20160605023335p:plain f:id:ne5oku:20160605023337p:plain f:id:ne5oku:20160605023338p:plain f:id:ne5oku:20160605023340p:plain

何を喋ったかとか普通に覚えてないです。申し訳ない。

今後は、マイクラを「オンラインゲームに見立てる」というのを主眼に置いて色々喋れたらいいかなと思っています。

まとめ

  • 水曜4限はあけよう
  • 金曜昼休みはあけよう
  • マイクラをかおう

*1:ライトニングトーク(英: Lightning Talks)とはカンファレンスやフォーラムなどで行われる短いプレゼンテーションのこと。様々な形式があるが、持ち時間が5分という制約が広く共有されている。 Wikipediaより

SD攻略決死隊 - 例外より課題処理 #2

2年以降向け SD/NS ネ学

先週(2016/5/19)のSDは例外処理でした。問題数の割には意外と簡単だったのでは無いでしょうか。
(というかその前が鬼畜すぎた)

後、某サークルに今年から加入しました。先週はちょうど合宿という事で色々な人と喋る事が出来ました。
今後ともぜひよろしくお願いします。

今回の課題

問題数が多かったですね。一個一個はそこまで重くないです。と思ってました。 1. 例外処理のメリット 2. TurtleOutOfFrameExceptionを作ってみる 3. 指定されたプログラムの動作を確認、例外処理の追加 4. マージソートについて調べて記述 5. MyListにマージソートを実装 6. 例外処理の便利さを身を持って知る

今回ヤバいのは課題6です。それ以外は割りと簡単。課題5で躓いてる人は先週の実装がガバかった人です。

例外を身を持って知る

課題1を突破した皆さんなら、「例外がいかに素晴らしいか」というのを分かっているはずです。
では、それを身をもって体感してみましょう、というのが課題6です。

例外処理はマジ便利

例外処理、一体なんなんだマジ死んでくれって感じの人も多いと思います。わかります。

めんどくさいものは図で考えましょう。処理というのは以下のような感じです。 f:id:ne5oku:20160526000146p:plain

メソッドが連なって連なって、「処理を担当するキャラ」がどんどん変わっていきます。

ここで問題が発生!

f:id:ne5oku:20160526000352p:plain

「処理を頼まれたんだけど、何らかの原因で処理ができなかった」
こうなると大変です。

あると思っていた5億が無い事に気付いたネコは、タートルさんに報告しなければいけません。
そして、タートルさんは神様である私たちの所に「5億なんてなかったよ」って教えてくれます。

その機能を実現するためには、タートルさんとネコに「エラーを報告する」とか「エラーを受け取る」とかそういう機能を追加しなければいけません。
これって非常にムダだよね!

今回はタートルさんとネコしか居なかったので、まだ良いですが、これがもっと多かったら…エラーを神様サイドへ運ぶために、多大な労力が必要です。
もしこれが再帰処理(!)だったら…めんどくさいったらありゃしない!(ちなみにマージソート再帰処理なのでこの面倒くさいのを課題6で実装しろと僕らの神が仰っております)

ここで登場するのがtryシステム

イメージとしては、「処理を頼み始めたヤツが、責任を持って部下の仕事を見張る」ような感じです。
今回の場合は「5億とってこいよ」と言っているのは左側の神様です。神様が、エラーを見張るのです。
そして、エラーを見つけたら「あ、5億無い?そかそかwんじゃ終わりでいいよw」とcatchブロックへ処理を移動します。

課題6への応用

課題6は「エラー」を「見つけた数」と置き換えて考えてみましょう。
つまり「数を見つけて、上司にreturnする」機能と「部下が見つけた数がreturnされてきたからそれを上司にreturnする」機能が必要なわけです。

まとめ

  • 責任は取ろう

謝辞

今回は、睡眠と猫が捗りすぎたため、短い記事な上に投稿日時が遅れてしまいました。申し訳ありません。
本当はもうちょい色々書きたかったのですが、時間も時間なので一番大事そうな所だけ書いておきました。
これ以外の所は多分教科書に乗ってます。

文系ウェイでも分かるオブジェクト死行(デスマーチ)入門

2年以降向け SD/NS ネ学

文系ウェイにはやっぱわからないと思います。

例外処理について書こうと思ったのですが、まず最初に記しておくべきネタがあったので、こちらを先に書きます。

これは、先週の課題に関してTwitterで疑問点がぽつぽつと見られたので、それに対する僕なりの答え的な感じでまとめたいと思います。

オブジェクト指向*1を知ろう ~ 手続き型Gotoをぶち○せ

オブジェクト指向って聞いただけで反吐が出るぜ!みたいな人も多いと思います。
それは食わず嫌いです。こいつ滅茶苦茶便利です。

まず何より、プログラミングしている時は「俺が神だ」と思い続けることが大切です。
自分は神なので、なんでもありです。やりたい放題です。

注意点があります。神の相方が「パソコン」な事です。これが最高にBAD。
相方が「美少女」とか「イケメン」だったらなんとなーく察してくれて、融通の効いたことをしてくれるはずです。
しかし相手はパソコン。超硬派(文字通り)です。指示しない限りは動いてくれませんし、言外を察するなんてしてくれません。

以上のことを念頭に置いて、読み進めて頂けると幸いです。

最初に

オブジェクト指向と言ったら、3つの特徴が挙げられます。二年次以降だと様々な授業で登場します。
- カプセル化 - 継承 - 多様性(ポリモーフィズム)

けどこれ、全部忘れて下さい。オブジェクト指向をある程度理解出来た人は「あぁ、そうだよね」ってなりますが、
全くの初心者にこれを言うのは逆効果なのでは無いかと考えます。

何故かというと、上記の3つの考え方はオブジェクト指向の「ある機能」から派生しているに過ぎないからです。
その根幹を知らずに利点だけたらたら述べられても、理解出来ません。僕もそうでした。

オブジェクト指向の「ある機能」

では、その「ある機能」について考えてみます。

オブジェクトとは「モノ」のことです。モノというよりかは「キャラクター(登場人物)」と考えると良いかもしれません。
オブジェクト指向のプログラミングでは、このキャラクター達を使ってプログラミングを行っていきます。

今までのプログラミングは、神である自分が「わざわざ」一個一個キャラクターを作り上げて、必要なら操作を行う必要がありました。
箱を積み上げていくようなイメージです。神である自分が「わざわざ」動き、箱を一個一個丁寧に積み上げていく。

いやめんどくさいじゃん

f:id:ne5oku:20160521014030p:plain

これが事の発端です。「もーマジだりい箱に足生えて勝手に移動してくれねーかなー」みたいな事を考える訳です。
勝手にやってくれれば神的には超オーケーです。みんなに「うごけ~」って言うだけで動いてくれるんです。

「箱」という登場人物を作り、足を生やし(?)、動けと言ったら動くようにする。この一連のある意味の設計図みたいなものが「クラス」です。

クラスという設計図と使い方

あえてソースコードを書くとしたらこんな感じでしょうか。

public class MyBox {
    //動く機能
    public void move() {
        //動けと言われたので渋々動く処理
    }
}

C言語しか触れたことない人からすると「え?箱だけでこんななんかこう偉そうじゃね?」って感じの書き方です。
少し贅沢な書き方な気がしますよね。けど慣れるしかないです。

設計図みたいなものを用意出来ました。これでオブジェクト指向の半分はクリアです。

「登場人物」として箱を用意することが出来ました。しかしこれは設計図の段階です。
さすがの神といえど、設計図という概念をコネコネすることは出来ません。

神が処理を書いていく「舞台」に登場させる必要があります。それが「new」演算子です。
設計図として書いた「クラス」をC言語でいう変数の「型」として扱える訳です。ワーオ。
Javaなどを扱う上で、ここを少し取り違えて覚えている人がいるので気をつけましょう。

String neko;             //文字が舞台に来ることを宣言した
neko = "kawaii";         //文字を舞台に召喚した
String mozi = "tikuwa";  //上2つを同時にこなした

MyBox hako;              //箱が舞台に来ることを宣言した
hako = new MyBox();      //箱を舞台に召喚した
MyBox heko = new MyBox();//上2つを同時にこなした

時々「舞台にxxx来るってさー」って言っときながら、実際に舞台にはxxxを召喚しないホラ吹きが居ます。
そういう事をしているとNullPointerException*2さんが来てめちゃくちゃ怒ってきます。気をつけましょう。 f:id:ne5oku:20160521020220p:plain

ここまで分かってしまえば、オブジェクト指向の9割を理解したようなものです。

パソコンに「ザックリ」捉えさせる

さて、この一見便利そうなクラス。実は少し不便な点があります。
このような状況を考えてみて下さい。

public class Turtle {
    public void move() {
        //動けと言われたので渋々動く
    }
}

public class Cat {
    public void move() {
        //動けと言われたので渋々動く
    }
}

public class Main {
    public static void main(String[] args) {
        Cat neko = new Cat();
        Turtle neko = new Turtle();
        //動物園に居る奴らを名簿(List)に登録したい
        List meibo = new ArrayList< >(10);
        //                         ↑Listに登録出来る「型」は一つにしなきゃいけない
        
    }
}

ArrayListという、決められた型の名簿みたいなものを使う時を考えてみます。
名簿に登録出来る型は「一種類です」なので、例えば猫の名簿を作りたかったら

List meibo = new ArrayList<Cat>(10);

のように<>の中にその型を書いてあげる必要が出てきます。

しかし、今回は動物園(?)に召喚した亀と猫を名簿に登録したいのです。猫だけ、亀だけという風に登録したいのではありません。
もし相方がイケメンなら「亀?あぁ動物の名簿に加えておくね」「数字?そりゃ動物じゃないだろ」みたいな感じで気を利かせてくれます。
つまり、パソコンは「亀」と「猫」の共通点を知らないのです。それをパソコンに教えてやる必要があるわけです。

ここで出てくる継承

では、どうやったら「亀」と「猫」は「動物」だよと示すことが出来るのでしょうか。
ここで「extends」という言葉が出てきます。 f:id:ne5oku:20160521021623p:plain 「亀」のもとを辿れば「動物」。「猫」も、もとを辿れば「動物」。

オブジェクト指向風に言い換えると「猫クラスは動物クラスを継承している」「亀クラスは動物クラスを継承している」。
ソースコードだとこのように書けます。

public class Animal() {
        //浜口ではない
}

public class Turtle extends Animal {
}

public class Cat extends Animal {
}

public class Main {
    public static void main(String[] args) {
        Cat neko = new Cat();
        Turtle neko = new Turtle();
        //舞台に居る奴らを名簿(List)に登録したい
        List meibo = new ArrayList<Animal>(10);
        //「Animal」が入る名簿にすれば猫も亀も入る!
    }
}

継承という機能の表面だけを教わる事が多いかもしれませんが、本質はここにあります。
登場人物達を「ザックリとらえる」ことを「多様性」といいます。
そして、その「多様性」を実現するために「継承」を使いました。

ここで一気に伏線回収した感じです。

SDなどの授業とうまくやるために

今回ここで考えてみた「オブジェクト指向」はかなり一部分で、しかも僕が勝手に「まずここを知らないと」みたいなポイントをおさえただけなので、この記事を読んだからと言ってSDの課題がスラスラ進んだり、自動的にオブジェクト指向技術の授業の単位が降ってきたりする訳ではありません。
僕としても、オブジェクト指向に対する理解はまだまだ未熟なので、今後もこの記事はシリーズとして続けて、色々と考えていきたいと思います。
(カプセル化の説明も残してしまいましたので!)

今までなんとなく書かされていたコード達も、このような知識を得ることで「意味がある」ものになると考えます。
僕自身も、Minecraftの追加要素開発からプログラミングを始めましたが(もう一年経ちますね)、最初はチュートリアルのコピペでした。
なんとなーく予測しながらプログラミングすることも大切ですが、知らないモノを扱うのは大変気が滅入ります。

まとめ

  • 自分は神
  • パソコンは融通が効かない
  • 設計図と舞台
  • 猫は可愛い

*1:今回はJavaベースで考えます

*2:通称ヌルポ。ガッと叩く。