実践的なプログラミング:API活用と基本的なユーティリティクラス

Javaのオブジェクト指向を学ぼう!

はじめに

Javaを学び始めると、必ず耳にする「オブジェクト指向」という言葉。これを理解すれば、Javaプログラミングがぐっと楽しくなります!最初は少し難しく感じるかもしれませんが、基本を押さえれば心配ありません。本記事では、以下の3つのキーワードを中心にオブジェクト指向を解説していきます。

  • クラスとオブジェクト

  • カプセル化

  • 継承とポリモーフィズム

最後には簡単な実践例も交え、オブジェクト指向の理解を深める手助けをします。ぜひ最後まで読んでみてください。


1. クラスとオブジェクト

クラスとは何か?

クラスは、設計図のようなものです。

例えば、コーヒーショップでは、メニューに登録するための設計図として「コーヒー」というクラスがあるとします。この設計図をもとに、ラテやエスプレッソといった具体的なコーヒー(オブジェクト)を作成します。

// コーヒークラスの定義
class Coffee {
    String name;  // コーヒーの名前
    double price; // 値段

    // コーヒーの情報を表示するメソッド
    void displayInfo() {
        System.out.println(name + ": ¥" + price);
    }
}

オブジェクトとは何か?

オブジェクトは、クラスを基に作られる具体的な「実体」です。
以下の例では、ラテやエスプレッソがオブジェクトに該当します。

class Main {
    public static void main(String[] args) {
        // コーヒーオブジェクトを生成
        Coffee latte = new Coffee();
        latte.name = "ラテ";
        latte.price = 400;

        Coffee espresso = new Coffee();
        espresso.name = "エスプレッソ";
        espresso.price = 300;

        // コーヒー情報を表示
        latte.displayInfo();
        espresso.displayInfo();
    }
}

出力例:

ラテ: ¥400  
エスプレッソ: ¥300

クラスとオブジェクトの違いが少し明確になったでしょうか? 次に、カプセル化について解説します。

2. カプセル化

カプセル化とは、「データを外部から隠し、安全に操作する」仕組みのことです。Javaでは、アクセス修飾子(`private`や`public`など)を使うことでこれを実現します。

例えば、コーヒーショップで注文を受けるとき、お客様が入力するのは「コーヒーの名前」と「数量」だけです。計算ロジックを外部から直接操作されるとトラブルが発生するかもしれません。そこで、必要最低限の操作だけを公開する仕組みがカプセル化です。

改善前のコード

以下のコードでは、フィールドがすべて公開されているため、無効なデータが簡単に設定されてしまうリスクがあります。

class Order {
    public String coffeeName;
    public int quantity;
    public double price;

    // 合計金額を計算するメソッド
    public double calculateTotal() {
        return quantity * price;
    }
}

改善後のコード

フィールドを`private`に設定し、値の設定と取得を専用のメソッドで管理します。

class Order {
    private String coffeeName;
    private int quantity;
    private double price;

    // コンストラクタで初期化
    public Order(String coffeeName, int quantity, double price) {
        this.coffeeName = coffeeName;
        setQuantity(quantity);
        setPrice(price);
    }

    // 数量を設定(0以上のみ許可)
    public void setQuantity(int quantity) {
        if (quantity > 0) {
            this.quantity = quantity;
        } else {
            System.out.println("数量は1以上で指定してください。");
        }
    }

    // 価格を設定(0以上のみ許可)
    public void setPrice(double price) {
        if (price > 0) {
            this.price = price;
        } else {
            System.out.println("価格は0以上で指定してください。");
        }
    }

    // 合計金額を計算
    public double calculateTotal() {
        return quantity * price;
    }

    // 注文の詳細を表示
    public void displayOrder() {
        System.out.println(coffeeName + " × " + quantity + " : ¥" + calculateTotal());
    }
}
public class Main {
    public static void main(String[] args) {
        Order order = new Order("ラテ", 2, 400);
        order.displayOrder();
    }
}

出力例:

ラテ × 2 : ¥800

3. 継承とポリモーフィズム

継承

継承は、「親クラス(既存のクラス)の特徴や動作を、子クラスが受け継ぐ仕組み」です。

たとえば、通常のお客様と会員のお客様の違いを表現するには、共通部分を`Customer`クラスに定義し、会員専用の処理を別のクラスに追加します。

親クラス: 共通の機能

class Customer {
    protected String name;

    public Customer(String name) {
        this.name = name;
    }

    public double calculatePrice(double basePrice) {
        return basePrice;
    }

    public void displayInfo(double basePrice) {
        System.out.println(name + "の料金: ¥" + calculatePrice(basePrice));
    }
}

子クラス: 特定の機能を追加

class MemberCustomer extends Customer {
    public MemberCustomer(String name) {
        super(name);
    }

    @Override
    public double calculatePrice(double basePrice) {
        return basePrice * 0.9; // 10%割引
    }
}

使用例

public class Main {
    public static void main(String[] args) {
        Customer regular = new Customer("通常顧客");
        Customer member = new MemberCustomer("会員顧客");

        double basePrice = 400;

        regular.displayInfo(basePrice);
        member.displayInfo(basePrice);
    }
}

出力例:

通常顧客の料金: ¥400  
会員顧客の料金: ¥360

ポリモーフィズム

ポリモーフィズム(多態性)とは、同じインターフェースや親クラスを持つオブジェクトが、それぞれ異なる動作を実現する仕組みのことです。

例: 支払い方法の実装

interface Payment {
    void pay(double amount);
}

class CashPayment implements Payment {
    public void pay(double amount) {
        System.out.println("現金で¥" + amount + "を支払いました。");
    }
}

class CardPayment implements Payment {
    public void pay(double amount) {
        System.out.println("クレジットカードで¥" + amount + "を支払いました。");
    }
}

public class Main {
    public static void main(String[] args) {
        Payment cash = new CashPayment();
        Payment card = new CardPayment();

        double amount = 500;

        cash.pay(amount);
        card.pay(amount);
    }
}

出力例:

現金で¥500を支払いました。  
クレジットカードで¥500を支払いました。

最後に

本記事では、オブジェクト指向の基本概念について紹介しました。

  • クラスとオブジェクト: 設計図(クラス)と具体的な実体(オブジェクト)

  • カプセル化: 内部ロジックを隠し、安全にデータを操作

  • 継承とポリモーフィズム: 親クラスを基にした柔軟な拡張

これらを理解することで、実際のプログラミングで問題を効率よく解決できるようになります。ぜひ、自分でコードを書いて練習してみてください!

いいなと思ったら応援しよう!