NEGAKULIFE

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

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

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

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

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

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

これは、先週の課題に関して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:通称ヌルポ。ガッと叩く。