プログラミング/オブジェクト指向プログラミング

オブジェクト指向プログラミングとは

編集

オブジェクト指向プログラミング(OOP)は、現実世界のエンティティをプログラム内のオブジェクトとして表現するプログラミングパラダイムです。「もの」を中心に考え、それぞれのオブジェクトが独自の状態と振る舞いを持つというアプローチを取ります。

OOPの主要な概念

編集
  1. クラスとオブジェクト
  2. カプセル化
  3. 継承
  4. ポリモーフィズム

クラスとオブジェクト

編集

言語別クラス定義の比較

編集
public class Car {
    // インスタンス変数(属性)
    private String model;
    private int year;
    
    // コンストラクタ
    public Car(String model, int year) {
        this.model = model;
        this.year = year;
    }
    
    // メソッド
    public void startEngine() {
        System.out.println(model + "のエンジンを始動");
    }
}
class Car {
private:
    string model;
    int year;

public:
    // コンストラクタ
    Car(string m, int y) : model(m), year(y) {}
    
    void startEngine() {
        cout << model << "のエンジンを始動" << endl;
    }
};
struct Car {
    model: String,
    year: u32,
}

impl Car {
    fn new(model: String, year: u32) -> Car {
        Car { model, year }
    }
    
    fn start_engine(&self) {
        println!("{}のエンジンを始動", self.model);
    }
}
public class Car {
    // プロパティ
    public string Model { get; set; }
    public int Year { get; set; }
    
    // コンストラクタ
    public Car(string model, int year) {
        Model = model;
        Year = year;
    }
    
    // メソッド
    public void StartEngine() {
        Console.WriteLine($"{Model}のエンジンを始動");
    }
}

カプセル化

編集

カプセル化は、オブジェクトの内部状態を保護し、外部からの直接アクセスを制限する仕組みです。

アクセス修飾子の例

編集
public class BankAccount {
    // プライベート変数
    private double balance;
    
    // パブリックメソッドを通じてのみアクセス可能
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    public double getBalance() {
        return balance;
    }
}
class BankAccount {
private:
    double balance;

public:
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    double getBalance() {
        return balance;
    }
};

継承

編集

継承は、既存のクラスの特性を新しいクラスに引き継ぐメカニズムです。

多言語での継承例

編集
public class Animal {
    protected String name;
    
    public void eat() {
        System.out.println(name + "が食べています");
    }
}

public class Dog extends Animal {
    public void bark() {
        System.out.println(name + "が吠えています");
    }
}
struct Animal {
    name: String,
}

impl Animal {
    fn eat(&self) {
        println!("{}が食べています", self.name);
    }
}

struct Dog {
    animal: Animal,
}

impl Dog {
    fn bark(&self) {
        println!("{}が吠えています", self.animal.name);
    }
}

ポリモーフィズム

編集

メソッドのオーバーライド

編集
public class Shape {
    public virtual double CalculateArea() {
        return 0;
    }
}

public class Circle : Shape {
    public double Radius { get; set; }
    
    public override double CalculateArea() {
        return Math.PI * Radius * Radius;
    }
}

public class Rectangle : Shape {
    public double Width { get; set; }
    public double Height { get; set; }
    
    public override double CalculateArea() {
        return Width * Height;
    }
}

高度な概念

編集

抽象クラスとインターフェース

編集
public abstract class Vehicle {
    public abstract void move();
}

public interface Flyable {
    void fly();
}

public class Airplane extends Vehicle implements Flyable {
    @Override
    public void move() {
        System.out.println("飛行機が移動");
    }
    
    @Override
    public void fly() {
        System.out.println("飛行機が空を飛ぶ");
    }
}

デザインパターン入門

編集

シングルトンパターン(Java)

編集
public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    private DatabaseConnection() {}
    
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
}

OOPの落とし穴と注意点

編集
  1. クラスの過剰な継承を避ける
  2. 単一責任の原則を意識する
  3. コンポジションを継承よりも優先する
  4. 抽象度と具象度のバランスを取る

まとめ

編集

オブジェクト指向プログラミングは、複雑なシステムを理解しやすく、保守性の高いコードを作成するための強力なアプローチです。各言語の特性を理解しながら、柔軟に適用することが重要です。