javaで理解するオブジェクト指向

# はじめに
プログラミングの勉強をしている上で、オブジェクト指向という壁にぶつかると思います。
オブジェクト指向を勉強する上で、よく車などの例で教えてもらうことがあると思います。
その時になんとなく理解したつもりになってそのままにしていることがあると思います。
しかしプログラミングを学んでいく中で、オブジェクト指向は避けて通れません。
ここではjavaを用いて生徒の点数を表示するプログラムを記述している。

# 今回作成するプログラム
今回は生徒の点数とその科目ごとの平均点を表示するプログラムを作成していきます。
具体的には
```
Aさん
数学:90, 英語:90, 理科:80
Bさん
数学:70, 英語:70, 理科:90
Cさん
数学:30, 英語:30, 理科:60
平均点
A:73, B:71, C:58
```
というような出力結果が出るようにプログラムを記述していきます。
その上でオブジェクト指向を用いない場合と用いる場合を見比べてもらいます。

# オブジェクト指向を用いないプログラム
以下のコードはオブジェクト指向を用いてないものです。

```java:Main.java
public class Main{
    public static void main(String[] args){
        //３人の数学・英語・理科の点数を定義
        int A_math = 90;
        int A_English = 50;
        int A_science = 80;
        int B_math = 70;
        int B_English = 55;
        int B_science = 90;
        int C_math = 30;
        int C_English = 85;
        int C_science = 60;
        //3人の平均点計算
        int ave_A = (A_math + A_English + A_science) / 3;
        int ave_B = (B_math + B_English + B_science) / 3;
        int ave_C = (C_math + C_English + C_science) / 3;
        //3人の数学・英語・理科の点数表示
        System.out.println("Aさん");
        System.out.println("数学:" + A_math + ", 英語:" + A_math + ", 理科:" + A_science);
        System.out.println("Bさん");
        System.out.println("数学:" + B_math + ", 英語:" + B_math + ", 理科:" + B_science);
        System.out.println("Cさん");
        System.out.println("数学:" + C_math + ", 英語:" + C_math + ", 理科:" + C_science);
        //3科目の平均点表示
        System.out.println("平均点");
        System.out.println("A:" + ave_A + ", B:" + ave_B + ", C:" + ave_C);
    }
}
```
```:実行結果
Aさん
数学:90, 英語:90, 理科:80
Bさん
数学:70, 英語:70, 理科:90
Cさん
数学:30, 英語:30, 理科:60
平均点
A:73, B:71, C:58
```

このコードを見てわかる通りA,B,Cさんの数学、英語、理科の点数をそれぞれ変数として定義しなければならないです。また表示するときも同じような処理を繰り返してしまっています。
これらから上のコードでは似たような処理がたくさんあることがわかります。

# オブジェクト指向を用いたプログラム
以下のコードは簡単にオブジェクト指向を用いたものです
```java:Main.java
import java.util.ArrayList;
public class Main {
    public static void main(String[] args) {
        String studentNames[] = {"A", "B", "C"};
        int studentScore[][] = {{ 90, 50, 80}, { 70, 55, 90}, { 30, 85, 60}};
        ArrayList<Student> students = new ArrayList<Student>();
        //インスタンス生成してlistに追加
        for(int i = 0; i < studentNames.length; i++){
            Student student = new Student(studentNames[i], studentScore[i][0], studentScore[i][1], studentScore[i][2]);
            students.add(student);
        }
        //3人の全科目表示
        for(int i = 0; i < students.size(); i++){
            students.get(i).printScore();
        }
        //3人の平均点を表示
        System.out.println("平均点");
        for(int i = 0; i < students.size(); i++){
            System.out.print(students.get(i).name + ":" + students.get(i).average() + " ");
        }
    }
}
```
```java:Student.java
public class Student {
    String name;
    int math;
    int English;
    int science;
    //平均点計算
    public int average(){
        return (this.math + this.English + this.science) / 3;
    }
    //全科目点数表示
    public void printScore(){
        System.out.println(this.name + "さん");
        System.out.println("数学:" + this.math + ", 英語:" + this.English + ", 理科:" + this.science);
    }
    //コンストラクタ
    public Student(String n, int m, int E, int s){
        this.name = n;
        this.math = m;
        this.English = E;
        this.science = s;
    }
}
```

このStudent.javaのようにStudentクラスを用意します。
Main.javaでStudentクラスのインスタンスを人数分生成します。
このようにオブジェクト指向を用いることでさっきまでの似たような処理たちをfor文でまとめて処理できるようになります。
またStudentクラス内のaverage関数を呼び出すことで、簡単に平均値を求めることができます。

# オブジェクト指向の利点
上記に挙げた利点以外にもオブジェクト指向の利点を２つ上げたいと思う。

1つ目は今回の例で言ったら、生徒情報を追加したいときにオブジェクト指向を用いているコードの方が修正しやすいことです。
オブジェクト指向を用いていない方を修正する時には、変数を増やして、平均点の計算を追加して、printlnの文も増やさなくてはいけないが、オブジェクト指向を用いてないコードを修正するにはstudentNamesに名前を、studentScoreに点数を記入するだけでいいのです。

2つ目はStudentとして一つの配列やlistにまとめることができることです。
今回String型のnameとint型の点数があるが、オブジェクト指向を用いないとこれらを一つの配列やlistにまとめることができません。
オブジェクト指向を用いるとStudent型として配列やlistでまとめることができ、Student内のフィールドとしてnameや点数を定義してあるので実質String型とint型を一緒にまとめることができているのです。

# まとめ
このようにオブジェクト指向は簡単にいうと設計図を作り、それを用いて具現化することである。
今回のように似たような処理を繰り返す時や、studentのように同じタイプの複数のモノが出てくる時にオブジェクト指向を用いた方がメリットが大きいです。