目次
はじめに
前回の関数とスコープの解説に続き、今回はPHPにおけるオブジェクト指向プログラミング(OOP)の基礎について学んでいきます。OOPは、コードをより整理された、再利用可能な形で書くための重要な概念です。
クラスとオブジェクト
クラスの基本
<?php
class User {
// プロパティ(クラスの変数)
private $name;
private $email;
private $age;
// コンストラクタ
public function __construct(string $name, string $email, int $age) {
$this->name = $name;
$this->email = $email;
$this->age = $age;
}
// メソッド(クラスの関数)
public function getName(): string {
return $this->name;
}
public function getEmail(): string {
return $this->email;
}
public function getAge(): int {
return $this->age;
}
}
オブジェクトの作成と使用
// オブジェクトのインスタンス化
$user = new User("山田太郎", "yamada@example.com", 25);
// メソッドの呼び出し
echo $user->getName() . "\n"; // 出力: 山田太郎
echo $user->getEmail() . "\n"; // 出力: yamada@example.com
echo $user->getAge() . "\n"; // 出力: 25
アクセス修飾子
PHPには3つのアクセス修飾子があります:
- public: クラスの外部からアクセス可能
- private: 同じクラス内からのみアクセス可能
- protected: 同じクラスと子クラスからアクセス可能
class Product {
public $name; // 外部からアクセス可能
private $price; // クラス内部のみ
protected $category; // 継承したクラスでも使用可能
public function __construct(string $name, int $price, string $category) {
$this->name = $name;
$this->price = $price;
$this->category = $category;
}
// privateプロパティにアクセスするためのメソッド
public function getPrice(): int {
return $this->price;
}
}
継承
クラスの機能を別のクラスに引き継ぐことができます:
class User {
protected $name;
protected $email;
public function __construct(string $name, string $email) {
$this->name = $name;
$this->email = $email;
}
}
class AdminUser extends User {
private $accessLevel;
public function __construct(string $name, string $email, int $accessLevel) {
parent::__construct($name, $email);
$this->accessLevel = $accessLevel;
}
public function hasFullAccess(): bool {
return $this->accessLevel >= 5;
}
}
インターフェースと抽象クラス
インターフェース
interface PaymentInterface {
public function processPayment(float $amount): bool;
public function refund(float $amount): bool;
}
class CreditCardPayment implements PaymentInterface {
public function processPayment(float $amount): bool {
// クレジットカード決済の処理
return true;
}
public function refund(float $amount): bool {
// 返金処理
return true;
}
}
抽象クラス
abstract class Vehicle {
protected $brand;
abstract public function start();
public function getBrand(): string {
return $this->brand;
}
}
class Car extends Vehicle {
public function __construct(string $brand) {
$this->brand = $brand;
}
public function start() {
echo "エンジンを始動します\n";
}
}
実践的な例:ECサイトの商品管理システム
<?php
interface PricingInterface {
public function calculatePrice(): float;
public function applyDiscount(float $percentage): void;
}
abstract class BaseProduct {
protected $name;
protected $basePrice;
protected $stock;
public function __construct(string $name, float $basePrice, int $stock) {
$this->name = $name;
$this->basePrice = $basePrice;
$this->stock = $stock;
}
abstract public function getType(): string;
}
class PhysicalProduct extends BaseProduct implements PricingInterface {
private $weight;
private $shippingCost;
private $discountRate = 0;
public function __construct(
string $name,
float $basePrice,
int $stock,
float $weight,
float $shippingCost
) {
parent::__construct($name, $basePrice, $stock);
$this->weight = $weight;
$this->shippingCost = $shippingCost;
}
public function getType(): string {
return '物理商品';
}
public function calculatePrice(): float {
$price = $this->basePrice + $this->shippingCost;
if ($this->discountRate > 0) {
$price -= ($price * $this->discountRate);
}
return $price;
}
public function applyDiscount(float $percentage): void {
$this->discountRate = $percentage / 100;
}
}
// 使用例
$product = new PhysicalProduct("テストProduct", 1000, 10, 0.5, 500);
echo "商品タイプ: " . $product->getType() . "\n";
echo "通常価格: " . $product->calculatePrice() . "円\n";
$product->applyDiscount(20); // 20%割引を適用
echo "割引後価格: " . $product->calculatePrice() . "円\n";
注意点とベストプラクティス
- 単一責任の原則
- 各クラスは1つの責任のみを持つべき
- 必要に応じて適切に分割する
- カプセル化
- プロパティは原則privateかprotectedにする
- アクセサメソッド(getter/setter)を使用する
- 依存性の注入
- 外部のクラスやサービスは、コンストラクタで注入する
- 疎結合なコードを心がける
- SOLID原則の適用
- Single Responsibility(単一責任)
- Open/Closed(開放/閉鎖)
- Liskov Substitution(リスコフの置換)
- Interface Segregation(インターフェース分離)
- Dependency Inversion(依存性逆転)
まとめ
今回は、PHPのオブジェクト指向プログラミングの基礎について学びました。クラス、継承、インターフェース、抽象クラスなどの概念を理解することで、より構造化されたコードが書けるようになります。
練習問題
- 銀行口座を表すクラスを作成してください。以下の機能を実装してください:
- 残高の取得と設定
- 入金と出金の処理
- 残高不足時のエラー処理
- 従業員管理システムを作成してください:
- 基本的な従業員クラス
- 正社員とパートタイム従業員を表す子クラス
- 給与計算のインターフェース
- 各種従業員タイプに応じた給与計算の実装
次回は、PHPにおけるデータベース操作について解説していきます。お楽しみに!
コメント