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

Chapter 1. そもそも class って何だコラ

設計 Java

Java という言語 の記事です。
 プログラミングってのは割と複雑です。プログラミングってのはコンピュータに「あれして、これして、こういうときはこれやって、こんな手順でこういうことしてね」と指示を与えることです。コンピュータを動かすための指示を紡ぐことをプログラミングといいます。
 ところが、コンピュータが受け付けられる指示の種類ってたかが知れているのです。その一方でユーザーからは高い要求が来るわけで、どうしてもプログラミングっていう作業は複雑な作業になってしまいます。ということは、プログラマによるヒューマンエラーが入り込みやすいということです。いわば指示の間違いです。これがバグです。
 そこで、できるだけ複雑さを軽減するためにプログラミング言語というものがいくつも作られたわけです。そして、その中でも Java っていうのは、「コンピュータに指示間違いを見つける作業をお願いする」ことでバグの発生を防いでくれる言語なわけです。

 この記事を読んでいる人は恐らく Java のソースをちょっとぐらい見たことがあるかと思います。

さてこれ↓は何でしょうか?

class Apple {
    
    public Apple( int price ) {
        this.price = price;
    }
    
    // 値段
    public int price;
}

 これは、りんごを表現するクラスです。しかしこのりんご、名前こそ Apple ですが、値段しかパラメータがありません。どんなりんごか想像できませんね。なぜかというと、必要ない要素は含めていないからです。もっと糖度とか赤みとか産地とか、いろいろ情報を足すことはできますが、不要なので入れていません。これがすごく大切な事で、こうやって必要なパラメータだけを必要なぶんだけ取り出して適切な形にすることを「モデリング」といいます。作ろうとしているプログラムに適応させるために、りんごっていうのはこういうものですよ、と定義したわけです。

 では同じようにメロンを定義します。

class Melon {
    
    public Melon( int price, int weight ) {
        this.price = price;
        this.weight = weight;
    }
    
    // 値段
    public int price;
    // 重さ
    public int weight;
}

 メロンのモデリングが完了し、Melon クラスを定義しました。さて、これを使ってみます。

class Main {
    public static void main( String[] args ) {
        Apple a = new Apple( 100 );
        Melon m = new Melon( 500, 1000 );
        
        System.out.println( m.price );
    }
}

 コードが増えてきました。実行するとメロンの値段が表示されるプログラムです。ところで、もしも、こう書いていたらどうでしょうか。

class Main {
    public static void main( String[] args ) {
        Melon m = new Apple( 100 );
        System.out.println( m.price );
    }
}

これはコンパイルエラーになります。コンパイルエラーが発生したということは、「コンピュータにどういう指示を出したらいいかを決められないようなことを書くなボケ!」ということです。
 どうしてでしょうか。Apple にも Melon にも price があります。なのにエラーになるのです。コンパイラは恐らく、「Melon の変数 m に Apple を代入しちゃダメだ」、という旨のメッセージを出しているはずです。なぜダメかというと、変数 m は Melon だからです。Apple ではありません。もし仮にこれができてしまうと、例えば m.weight の値がいくつになるのか決めようがないのです。

 「じゃあとりあえず weight は 0 でいーじゃん」と思いがちですが、だったらなぜ「とりあえず 100 でいーじゃん」ではないのでしょうか。100 だと重さが 100 のものと区別がつきません。同じように 0 が何か意味を持つかもしれません。「メロンの重さだからここは 0 にしておけば、値をセットしていない、ってことは分かる」のは人間だからであって、コンピュータはそこまで関与しないわけです。

 従って、このように「異なる型への代入を許してしまうということは、意味的な不整合が起こることである」ってことが分かります。実行してみなくても、明確に間違いなのです。こういう、不整合を徹底的に排除して意地でも実行させない、まさにヒューマンエラーの介入を防ぐ機能が Java の強みなわけです。
 Java を扱うということは、コンピュータの助けを利用して、正しく実行するプログラムを書くということです。Java には、こうやって安全に意味を履き違えずに開発を行うためのしくみが、大量に備わっています。それらのうち、知っておくと良い(であろうと僕が思っている)ことを、いくつか噛み砕いていくつか紹介しようと思います。