Java silver 6章 継承とポリモフィズム②

#オブジェクト指向の三要素
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/186636fd-77b2-8026-52b8-a4cdf55a2ff8.png)


## カプセル化
オブジェクトの安全性を高めるために、オブジェクトのメンバーを保護すること
※メンバ = オブジェクトのメソッド及び変数
この性質を理解し、影響範囲の小さく疎なプログラミングを心がけることが、大規模で安全なシステム構築に繋がる。

他クラスから直接フィールドを操作せず、メソッドを通し間接的に操作する

## 継承
あるクラスを引き継いで新しいクラスを定義する

クラスの共通部分はスーパークラスで管理し、サブクラスで個別の処理を定義する

## ポリモーフィズム(多態性)
オーバライドやオーバロードによって、メソッドを状況によって使い分けることができること
※ オーバライド: 親クラスのメソッドを子クラスで上書きすること
※ オーバロード: 同一クラス内で引数の違いによってメソッドの呼び分けること

#colection
複数のオブジェクトをまとめて取り扱うための機能
配列と違いオブジェクトの数、種類に制限がない
![スキャン 2021-09-21 13.44.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/f6735b3e-c62f-5e3b-7af6-cb38ff88fb9b.jpeg)

#ジェネリクス


- 任意の型を受け付けるクラス・メソッドに対して`特定の型を割り当てて、型専用のクラスを生成する`機能
- これでメンバー要素の型をコンパイル時に保証できる

##Listインターフェース
サイズ変更可能な配列のようなもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/af1b06c3-48f0-e842-f5fa-c7ddfc7cd8d6.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/8452c136-11ab-101b-e2cb-0f5069e77ce2.png)


インスタンス化
ArrayList<データ型> 変数名 = new ArrayList<>();

```java
import java.util.ArrayList;
//コレクション関連の各インターフェースはjava,untilパッケージに含まれる

public class Main {
  public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<>();
    Integer i1 = 10;
    int i2 = 2;
    Integer i3 = i1;
    list.add(i1);
    list.add(i2);   // intデータはBoxingによりIntegerに変換
    list.add(i3);   // 重複要素
    list.add(1, 5); // インデックス1番目に5を追加
    //list.add("abc");　//
    System.out.println("size : " + list.size());
    for(int i = 0; i < list.size(); i++){
      System.out.print(list.get(i) + " ");
    }
    System.out.println();
    for(Integer i : list){ System.out.print(i + " "); }
  }
}
```

```
size : 4
10 5 2 10 
10 5 2 10
```

ArrayListオブジェクトに対して
add(配列番号, 要素名)　配列番号の場所に要素を追加　既に要素がある場合一つずつ後ろへスライド
get() 要素の取得
size() 要素数の取得
##Setインターフェース
データ構造に順不同で要素の重複を制限したい場合に使用する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/015a2e3f-a5f3-d0aa-b8c6-3c71bf1a1538.png)


HashSet<データ型> 変数名 = {要素,要素,…}

```java
import java.util.HashSet;

public class Main {
  public static void main(String[] args) {
    String[] ary = {"CCC","AAA","BBB"};
    HashSet<String> hashSet = new HashSet<String>();
    hashSet.add(ary[0]);  hashSet.add(ary[1]);
    hashSet.add(ary[2]);  hashSet.add(ary[0]);
    System.out.println("HashSet size : " + hashSet.size());
    for(String s : hashSet){ System.out.print(s + " "); } 
    //HashSet size : 3
    //AAA CCC BBB
  }
}
```

要素のソート機能を持つTreeSet

```java
import java.util.*;

public class Main {
  public static void main(String[] args) {
    HashSet<Integer> hSet = new HashSet<>();
    hSet.add(300); hSet.add(20); hSet.add(500);
    System.out.println("HashSet : " + hSet);
    TreeSet<Integer> tSet = new TreeSet<>();
    tSet.add(300); tSet.add(20); tSet.add(500);
    System.out.println("TreeSet : " + tSet);
  }
}
```
順不同のHashSetに対し、数値の昇順に並ぶTreeSet
##Mapインターフェース
データをキーと値のペアで管理する
PHPの連想配列と似ている

key：識別できるよう一意
値：重複可能

HashMap<Integer, String> map = new HashMap<Integer, String>();

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/db8b676d-4157-b229-c55b-60e07751cec6.png)

###コンストラクタによるオブジェクト作成、クラスの初期化

コンストラクタを伴うインスタンス化の書き方が覚えにくいので復習
クラス名 オブジェクト名 = new(コンストラクタの引数)

```java
public Class A {
  private String str;
  private int num;
  public A(String str, int num) {
    this.str = str;
    this.num = num;
  }
}

A a = new ("文字列", 数値);
```

### プリミティブ型と参照型
こちらも忘れたので復習
8つのプリミティブ型それぞれに、参照型であるラッパークラスが存在する

|プリミティブ型|ラッパークラス|
|-----------|------------|
|boolean|Boolean|
|char|Character|
|byte|Byte|
|short|Short|
|int|Integer|
|long|Long|
|float|Float|
|double|Double|

*Boxing:プリミティブ型をラッパ―クラスに代入する時、型が自動変換される

#オブジェクトの比較
Compareable/Comparatorインターフェースの利用
`Compareable`・`Comparator`インターフェースは`java.lang`にパッケージされており
実装したクラスに自然順序付け機能を提供する

具体的な方法

 - オブジェクトのクラスに`Comparable`インターフェースを実装し`compareTo`メソッドを定義
 - `Comparator`インターフェースを実装し`compare`メソッドを定義

##Comparable
`Comparable`インターフェースを実装し抽象メソッド`compareTo()`をオーバーライドする

宣言
public int compareTo(T O) 
T：比較対象のオブジェクトデータ型
O：比較対象

*オーバーライドしない場合のデフォルト設定
戻り値
自オブジェクト > 比較対象：正の値（通常＋１）を返す
自オブジェクト = 比較対象：ゼロを返す
自オブジェクト < 比較対象：負の値（通常−１）を返す

```java
//Numberクラスを継承したサブクラスIntegerクラスにComparableインターフェースを実装
public class Integer extends Number implements Comparable<Integer>{

  integer value = value;
  
  //compareToをオーバーライド
  //このクラスのフィールドvalueとAnotherIntegerクラスのvalueをcompareメソッドで比較
  //AnotherIntegerクラスはIntegerクラスとは別に定義されたクラスとする
  //引数のIntegerはデータ型の指定
  @Override
  public int compareTo(Integer AnotherInteger){ 
      //定義したcompareメソッドを使って戻り値をオーバーライド    
      return compare(this.value, AnotherInteger.value);
  }

  public static int compare(int x, int y){
   //x < yなら-1,  x = yなら0,  x > yなら1を返すメソッドを定義()
   return(x < y) ? -1 : ((x == y) ? 0 : 1 );
  }
}
```
コレクションであるjava.util.Collectio：`List`・`Set`・`Map`は実装された`CompareTo()メソッド`に従い、格納したオブジェクトを昇順に並べる

##Comparator
ソートの対象となるオブジェクト自身にcomrareTo()メソッドを実装するのではなく
比較ルールを独立したクラスとして定義する方法

```java
import java.util.*;
class Employee {
  private String name;
  private Integer id;
  public Employee(String name, Integer id) {
    this.name = name; this.id = id;
  }
  public Integer getId() { return id; }
  public String getName() { return name; }
}

//比較ルールを独立したクラスとして定義(comparatorを実装)
class MyRule implements Comparator<Employee> {
  public int compare(Employee obj1, Employee obj2) {
    //obj1のメンバidに対しcompareTo()メソッドでobj2のメンバidと比較する
    return obj1.getId().compareTo(obj2.getId());
  }
}
public class Main {
  public static void main(String[] args) {
    Employee e1 = new Employee("taro", 20);
    Employee e2 = new Employee("tomoko", 10);
    Employee e3 = new Employee("hiromi", 50);
    ArrayList<Employee> ary = new ArrayList<>();
    ary.add(e1); ary.add(e2); ary.add(e3);
    System.out.println("ArrayList のインデックス順での表示");
    print(ary);
    System.out.println("MyRule で定義したid の昇順での表示");
    //sort()メソッドを利用した並べ替え
    //第一引数にソート対象、第二引数に独自に作成したcomparatorインターフェースの実装クラス
    Collections.sort(ary, new MyRule());
    print(ary);
  }
  public static void print(ArrayList<Employee> ary) {
    for(Employee obj : ary){
      System.out.println(obj.getId() + " " + obj.getName());
    }
  }
}
```