0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java入門 - 実践編】さまざまな種類のクラス

0
Posted at

はじめに

こんにちは。
スッキリわかるJava入門 実践編の学習を進めています。
この学習記録を備忘録として残しながら、自身の理解を深めたいと思っています。

今回は第1部 / 2章「さまざまな種類のクラス」について学びました。
「ジェネリクス、列挙型、インナークラス」といった概念を通じて、一度作ったクラスを安全に再利用し、拡張可能な設計を実現することの大切さを学べました。

この記事が、同じくJavaの学習をしている人にとっても参考になりましたら幸いです。

参考書籍について

目次

  1. 本章の要点
  2. 自分なりの解釈

1. 本章の要点

型安全という価値

  • 格納するデータに制約をかける仕組み
    • 変数に予期しない種類の情報が入ってしまうことを未然に防ぐための安全装置です。

ジェネリクス

  • ジェネリクスとは
    • 型パラメータを使用して、クラスやメソッドで扱うデータ型を柔軟に指定できる仕組みです。
    • コンパイル時に型をチェックするため、実行時エラーを減らせます。
  • ジェネリクスによる安全機構
    • 型チェックが厳格になり、予期しない型の代入がコンパイルエラーになります。
  • ジェネリクスを使って宣言されたクラスは、<~>記法を利用できます。
// 基本的なジェネリクスクラス
class Box<T> {
    private T item;
    
    public void set(T item) {
        this.item = item;
    }
    
    public T get() {
        return this.item;
    }
}

public class Main {
    // ジェネリクスメソッド
    public static <T> void display(T value) {
        System.out.println("値:" + value);
    }
    
    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.set("ポーション");
        System.out.println(stringBox.get()); // 出力:ポーション
        
        Box<Integer> intBox = new Box<>();
        intBox.set(100);
        System.out.println(intBox.get()); // 出力:100
        
        display("テキスト"); // 出力:値:テキスト
        display(42); // 出力:値:42
    }
}

列挙型

  • 列挙型とは
    • 定められた限られた値のみを持つ特別なクラスです。
      • 例えば、ゲーム内の職業は「剣士」「魔法使い」「僧侶」など、決まった値のみを扱う場合に使用します。
public enum Job {
    SWORDSMAN("剣士"), WIZARD("魔法使い"), PRIEST("僧侶");
    
    private String displayName;
    
    Job(String displayName) {
        this.displayName = displayName;
    }
    
    public String getDisplayName() {
        return this.displayName;
    }
}

public class Hero {
    private String name;
    private Job job;
    
    public Hero(String name, Job job) {
        this.name = name;
        this.job = job;
    }
}

public class Main {
    public static void main(String[] args) {
        Hero hero = new Hero("ミナト", Job.SWORDSMAN);
        System.out.println(hero.getJob().getDisplayName()); // 出力:剣士
    }
}

インナークラス

  • インナークラスとは
    • クラスの中で定義されるクラスです。
    • 外部クラスと密接に関連する機能をカプセル化できます。
  • 3つの種類があります
    • メンバクラス(static修飾子の有無で役割が変わります)
      • staticメンバクラス
        • 外部クラスのインスタンスなしで利用できます。
        • 外部クラスのstaticメンバのみアクセス可能。
      • 非staticメンバクラス
        • 外部クラスのインスタンスが必須です。
        • 外部クラスの全メンバにアクセス可能。
public class Dungeon {
    // staticメンバクラス:外部クラスのインスタンスなしで使える
    static class Treasure {
        public void display() {
            System.out.println("宝物を発見!");
        }
    }
    
    // 非staticメンバクラス:外部クラスのインスタンスが必要
    private String dungeonName = "魔王の城";
    
    class Monster {
        public void appear() {
            System.out.println(dungeonName + "に怪物が現れた!"); // 外部クラスのメンバにアクセス
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // staticメンバクラス:外部クラスのインスタンスなしで使える
        Dungeon.Treasure treasure = new Dungeon.Treasure();
        treasure.display(); // 出力:宝物を発見!
        
        // 非staticメンバクラス:外部クラスのインスタンスが必須
        Dungeon dungeon = new Dungeon();
        Dungeon.Monster monster = dungeon.new Monster();
        monster.appear(); // 出力:魔王の城に怪物が現れた!
    }
}
  • ローカルクラス
    • メソッド内でのみ定義・使用できます。
    • そのメソッド内でしか利用できません。
public class Main {
    public static void main(String[] args) {
        class Message {
            public void show() {
                System.out.println("これはローカルクラス");
            }
        }
        
        Message msg = new Message();
        msg.show(); // 出力:これはローカルクラス
    }
}
  • 匿名クラス
    • 名前なしでその場で実装するクラスです。
    • インターフェースを実装する一度限りの処理に便利。
interface Greeting {
    void greet();
}

public class Main {
    public static void main(String[] args) {
        // 匿名クラスで即座に実装
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("こんにちは");
            }
        };
        greeting.greet();
    }
}

null安全性

  • Optionalクラス
    • nullの可能性を明示的に扱い、nullチェックをより安全に行うためのクラスです。
    • Optional.of()、Optional.ofNullable()、Optional.empty()で値を包みます。
    • isPresent()、ifPresent()、orElse()などのメソッドで安全に値を取り出します。
import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional<String> name = Optional.of("ミナト");
        
        // 値が存在するかチェック
        if (name.isPresent()) {
            System.out.println(name.get()); // 出力:ミナト
        }
        
        // nullの可能性がある場合
        Optional<String> nullable = Optional.ofNullable(null);
        System.out.println(nullable.orElse("デフォルト値")); // 出力:デフォルト値
    }
}

2. 自分なりの解釈

  • 型安全性を実装することで、予期しないデータ型が変数に入るのを防ぎ、バグの早期発見につながる。
  • ジェネリクスは型パラメータを使うことで、一つのクラスで複数の型に対応できるため、コードの再利用性が向上する。
  • 列挙型で限定された値のみを扱うことで、不正な値が入ることを防ぎ、switch文での処理が明確になる。
  • インナークラスを使うことで、関連する処理をまとめられ、匿名クラスを使えば一度だけ使う実装を素早く書ける。
  • Optionalクラスはnullチェックを強制的に意識させるため、NullPointerExceptionによるバグを減らせる。

最後まで見ていただきありがとうございました。
次回は、第1部 / 第3章「関数とラムダ式」について書く予定です。


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?