Javaについて初心者なりにまとめた

### 背景
新しい言語習得をしたいと思い、Javaの勉強をすることに。
そこで、まずは簡単なTODOアプリを作成してECSにデプロイしようという流れです。
環境構築は以下の記事から

https://qiita.com/hi_kun_kun/items/9acaf88e0ce7501b1e3e

---
### Javaについて

https://qiita.com/suke_qiita/items/772cb4c8770c0de44530

#### **Javaには2種類のクラスがある**
**1. 実行用クラス**

プログラムを実行するためのクラス
クラスの中にmainメソッドが含まれるもの


**2. 設計図クラス**

属性・操作を設定できるクラス

オブジェクト指向においてこのクラスがとても重要

属性：何の **データ** を持っているのか？変数を用いて用いて実現する。

(ex：教科、点数、名前 など)

操作：何の **処理** を出来るのか？メソッドを用いて実現する。

(ex：文字を表示する など)

具体的なデータを入れ込んで、生成される結果(クラスから作られる実体)が「オブジェクト」

**データと処理に基づいてプログラムを組む考え方が「オブジェクト指向」**

---
**設計図クラス**

```java
class クラス名 {
	変数の定義
	メソッドの定義
}
```

変数の定義は

```java
String name;
int point;
```

のような形で、型+変数名

属性として定義する変数のことをメンバー変数（クラス直下に定義されたもの）と言い、有効範囲はクラス内に限られる

メソッドの定義は

```java
戻り値の型 () {
	処理
}
```

例えばvoid型は戻り値がないため、処理の中に`return`を記載しない

```java
void display() {
	System.out.println(name + "さん");
}
```

これに対し

```java
double getScore() {
	double avg = (score1 + score2) / 2.0;
	return avg;
}
```

のように、返り値の型としてdouble型を想定しているので`return`が必要

---

**実行クラス**

設計図クラスで定義したクラスを使用して、インスタンスを作成

そのインスタンスから変数を呼び出したり、メソッドを呼び出したりする。

```java
class StuSample {
	public static void main(String[] args){
		Student stu1 = new Student(); //インスタンス化
		...クラスメソッドや変数を使った処理を記述
	}
}
```

ここで疑問

**1. なぜ実行クラスの関数名の前には `public static` をつけなければならないのですか？**

**理由1：`public` について**

- `public` は「どこからでもアクセス可能」というアクセス修飾子です。
- 実行クラスの `main` メソッドは、Javaプログラムのエントリーポイント（開始地点）です。JVM（Java Virtual Machine）がプログラムを起動する際に `main` メソッドを直接呼び出すため、アクセス可能である必要があります。

**理由2：`static` について**

- `static` は**「クラスに属するメソッドである」**という意味です。
- クラスのインスタンスを生成せずに直接呼び出すことが可能になります。
- JVMはプログラムを開始する際、クラスを読み込んでそのクラス内の `main` メソッドを呼び出しますが、このときクラスのインスタンスを生成せずに実行する必要があるため、`static` が必要です。

---

**2. `main` 関数の引数である `String[] args` はそれぞれ何を意味していますか？**

**`String[]` の意味**

- `String[]` は文字列（`String`）の配列を表す。
- Javaでは、配列は複数の値を格納するデータ構造で、`String[]` は複数の文字列を格納できる。

**`args` の意味**

- `args` は引数の名前で、プログラムを実行するときに外部から渡されるコマンドライン引数を受け取る。
- 例えば、コマンドプロンプトやターミナルから次のようにプログラムを実行すると、このとき、`args` には以下の文字列配列が渡されます。
    
    ```java
    java StuSample Hello World
    ```
    
    ```java
    args = {"Hello", "World"}
    ```
    

`main`関数の引数 `String[] args` は、**配列の形で1つまたは複数の文字列**を受け付ける仕様

---

**3. `Student stu1 = new Student();` について**

**`Student stu1` の意味**

- `Student` はクラス名（型）で、`stu1` は変数名。
- Javaではクラスも「型」の一種である。たとえば、`int` 型の変数 `x` を宣言する場合に `int x` と書くのと同じように、クラス型の変数を宣言する際にはクラス名を指定する。

---

**補足：コンパイルする際**

```java
javac -d <.classファイルの保存先> App.java
```

のようにすると、自動的にディレクトリが作成され、指定されたクラスのコンパイラファイルが作成される。（今回であればApp.javaの.classファイル）

これを実行する際は

```java
java -cp test App.java
```

のように、`-cp`オプションでコンパイラがどのディレクトリにあるかを指定する必要がある。

ざっくり理解したところで。今回のディレクトリ構成

```
src/
  ├── main/
  │     ├── App.java                   (エントリーポイント)
  │     ├── controller/                (コントローラー層: ユーザー入力や操作を処理)
  │     │     └── TodoController.java
  │     ├── service/                   (ビジネスロジック層: アプリケーションの処理)
  │     │     └── TodoService.java
  │     ├── model/                     (データモデル層: データ構造を定義)
  │     │     └── Todo.java
  │     └── database/                  (DB接続関連)
  │           └── DatabaseConnection.java
  └── test/                            (ユニットテスト用)
```

やることはそんなに多くない

- todoのクラス定義（属性やメソッドなど）
- CRUD処理
- データベース接続

くらい。今回は勉強も兼ねているので、必要ないかもだけどdockerも使用してみる。

---

**Controllerクラスについて**

ここではユーザーによるCRUD操作を処理する。

ここで、packageやimportの概念が出てくる

---

**Packageについて**

Javaのクラスやインターフェースをグループ化して整理するための仕組み

同じ名前のクラスが複数存在する場合でも、パッケージによって区別できる

以下要点

- **src直下**に `.java` ファイルを置く場合、パッケージ宣言は不要（デフォルトパッケージ）。
- **ディレクトリを作成してファイルを置く場合**、そのディレクトリ名に対応するパッケージ宣言が必須。
- **複数階層のディレクトリ**でも、パッケージ名を階層に合わせて指定する必要がある。
    
    例：`src/com/example/app/controller/TodoController.java` → `package com.example.app.controller;`
    

---

**サブクラスとは？**

親クラスを継承した子クラスのこと。

親クラスが持っているメンバ（属性やメソッド）を再利用できる。

```java
public class Dog extends Animal {
    @Override //これが必要
    public void makeSound() {
        System.out.println("Woof! Woof!");
    }
}
```

**サブクラスでは、異なるパッケージに親クラスがいる場合に、protectedされたメンバにもアクセスができる！**

---
今回はここまでにします。
次回はモデルの定義から！