سی ام اس نویسسی ام اس نویسیاد بگیر، سیستم خودتو بنویس
مجلهتماس با ما
سی ام اس نویسسی ام اس نویس

CMS نویس مرجعی برای آموزش برنامه نویسی وب و PHP، توسعه افزونه‌های اختصاصی وردپرس، طراحی ورک‌فلو و اتوماسیون با n8n و توسعه CMS های اختصاصی است. هدف ما ارائه آموزش‌های کاربردی و راهکارهای حرفه‌ای برای توسعه‌دهندگان، کسب‌وکارها و علاقه‌مندان به دنیای برنامه‌نویسی است.

پیوندهای سریع
محصولات فیزیکیمحصولات دیجیتالدوره‌های آموزشی
سی ام اس نویس
مجله سی ام اس نویستماس با ماپنل کاربری
سی ام اس نویس — تمامی حقوق برای سی ام اس نویس محفوظ است. © 1406 تماس با ما09307711941
Abstract Class در PHP چیست؟ آموزش کلاس انتزاعی در PHP با مثال

Abstract Class در PHP چیست؟ آموزش کلاس انتزاعی در PHP با مثال

ممدیر کل سیستم ۱۹ شهریور ۱۴۰۵ ۲۱ دقیقه مطالعه ۴ بازدید
Abstract Class در PHP چیست؟ آموزش کلاس انتزاعی در PHP با مثال

اگر با برنامه‌نویسی شی‌گرا در PHP (OOP) کار کرده باشید، احتمالاً با مفاهیمی مثل Class، Inheritance و Interface آشنا شده‌اید. یکی دیگر از مفاهیم مهم در طراحی ساختارهای شی‌گرا، Abstract Class یا «کلاس انتزاعی» است.

Abstract Class زمانی کاربرد دارد که بخواهیم یک ساختار پایه برای چند کلاس ایجاد کنیم، اما نخواهیم از آن کلاس به صورت مستقیم Object بسازیم.

به زبان ساده، یک Abstract Class می‌تواند بخشی از منطق مشترک کلاس‌های فرزند را در خودش قرار دهد و در عین حال، بعضی رفتارها را به کلاس‌های فرزند واگذار کند.

در این مقاله از مجموعه آموزش PHP در سی ام اس نویس، با مفهوم Abstract Class، نحوه تعریف آن، Abstract Method، ارث‌بری، Constructor، تفاوت آن با Interface و کاربردهای واقعی آن در پروژه‌های PHP آشنا می‌شویم.


Abstract Class در PHP چیست؟

Abstract Class کلاسی است که نمی‌توان مستقیماً از آن یک Object ایجاد کرد و معمولاً به عنوان کلاس پایه برای سایر کلاس‌ها استفاده می‌شود.

برای تعریف یک Abstract Class از کلمه کلیدی abstract استفاده می‌کنیم:


abstract class Animal

{

    // properties

    // methods

}

برای مثال:


$animal = new Animal();

این کد مجاز نیست، زیرا Animal یک Abstract Class است.

اما می‌توانیم از آن یک کلاس دیگر ایجاد کنیم:


class Dog extends Animal

{

}

در این حالت Dog می‌تواند از Animal ارث‌بری کند و از آن Object بسازیم:


$dog = new Dog();

بنابراین می‌توان گفت:

> Abstract Class بیشتر برای تعریف یک ساختار پایه و مشترک برای کلاس‌های دیگر استفاده می‌شود، نه ایجاد مستقیم Object.


# چرا از Abstract Class استفاده می‌کنیم؟

فرض کنید در یک پروژه فروشگاهی، چند نوع روش پرداخت داریم:

  • پرداخت با کارت بانکی
  • پرداخت با PayPal
  • پرداخت با کیف پول
  • پرداخت با ارز دیجیتال

همه این روش‌ها یک رفتار مشترک دارند:


پرداخت

اما نحوه انجام پرداخت برای هرکدام متفاوت است.

می‌توانیم یک Abstract Class ایجاد کنیم:


abstract class Payment

{

    abstract public function pay(float $amount): bool;

}

حالا هر روش پرداخت باید مشخص کند که pay() را چگونه پیاده‌سازی می‌کند.

مثلاً:


class BankPayment extends Payment

{

    public function pay(float $amount): bool

    {

        echo "پرداخت {$amount} تومان با کارت بانکی";



        return true;

    }

}

و:


class WalletPayment extends Payment

{

    public function pay(float $amount): bool

    {

        echo "پرداخت {$amount} تومان از کیف پول";



        return true;

    }

}

در این ساختار، کلاس Payment یک قرارداد پایه برای سیستم پرداخت ایجاد کرده است.


# Abstract Method در PHP چیست؟

یکی از مهم‌ترین ویژگی‌های Abstract Class امکان تعریف Abstract Method است.

Abstract Method متدی است که فقط تعریف می‌شود و بدنه ندارد.

مثلاً:


abstract class Payment

{

    abstract public function pay(float $amount): bool;

}

در اینجا متد pay() فقط تعریف شده است:


abstract public function pay(float $amount): bool;

اما مشخص نکرده‌ایم داخل آن چه اتفاقی بیفتد.

کلاس فرزند باید این متد را پیاده‌سازی کند.

مثلاً:


class BankPayment extends Payment

{

    public function pay(float $amount): bool

    {

        echo "پرداخت با کارت بانکی";



        return true;

    }

}


# تفاوت متد معمولی و Abstract Method

یک متد معمولی می‌تواند بدنه داشته باشد:


public function log()

{

    echo "Payment started";

}

اما Abstract Method بدنه ندارد:


abstract public function pay();

بنابراین:


abstract public function pay()

{

    // ...

}

برای Abstract Method ساختار درستی نیست.


# یک Abstract Class می‌تواند متد معمولی داشته باشد؟

بله.

این یکی از تفاوت‌های مهم Abstract Class با Interface است.

یک Abstract Class می‌تواند هم شامل:

  • Abstract Method
  • متد معمولی
  • Property
  • Constant
  • Constructor

باشد.

مثلاً:


abstract class Payment

{

    protected string $currency = 'IRR';



    abstract public function pay(float $amount): bool;



    public function getCurrency(): string

    {

        return $this->currency;

    }

}

حالا کلاس فرزند فقط لازم است رفتار مخصوص خودش را پیاده‌سازی کند:


class BankPayment extends Payment

{

    public function pay(float $amount): bool

    {

        echo "پرداخت {$amount}";



        return true;

    }

}

و متد getCurrency() را نیز از کلاس پایه دریافت می‌کند.


# ساخت اولین Abstract Class در PHP

بیایید یک مثال ساده‌تر ایجاد کنیم.

فرض کنید می‌خواهیم برای حیوانات یک ساختار پایه ایجاد کنیم.


abstract class Animal

{

    protected string $name;



    public function __construct(string $name)

    {

        $this->name = $name;

    }



    abstract public function makeSound(): string;



    public function getName(): string

    {

        return $this->name;

    }

}

در این کلاس:

  • name اطلاعات مشترک حیوان است.
  • Constructor مقدار نام را دریافت می‌کند.
  • makeSound() یک Abstract Method است.
  • getName() یک متد معمولی است.

حالا یک کلاس برای سگ ایجاد می‌کنیم:


class Dog extends Animal

{

    public function makeSound(): string

    {

        return 'Woof!';

    }

}

و برای گربه:


class Cat extends Animal

{

    public function makeSound(): string

    {

        return 'Meow!';

    }

}

اکنون می‌توانیم Object ایجاد کنیم:


$dog = new Dog('Max');

$cat = new Cat('Kitty');



echo $dog->getName();

echo $dog->makeSound();



echo $cat->getName();

echo $cat->makeSound();

اما نمی‌توانیم مستقیماً از Animal Object بسازیم:


$animal = new Animal('Animal');

چون Animal یک Abstract Class است.


# آیا Abstract Class باید Abstract Method داشته باشد؟

خیر.

این نکته مهم است.

یک Abstract Class می‌تواند حتی هیچ Abstract Method نداشته باشد.

مثلاً:


abstract class BaseModel

{

    public function log()

    {

        echo "Logging...";

    }

}

این کلاس همچنان Abstract است و نمی‌توان مستقیماً از آن Object ساخت.

اما اگر بخواهیم کلاس پایه را فقط برای جلوگیری از ساخت Object مستقیم و اشتراک منطق بین کلاس‌ها استفاده کنیم، چنین ساختاری می‌تواند مفید باشد.


# ارث‌بری از Abstract Class

برای ارث‌بری از Abstract Class از extends استفاده می‌کنیم:


abstract class User

{

    abstract public function getRole(): string;

}

کلاس فرزند:


class Admin extends User

{

    public function getRole(): string

    {

        return 'admin';

    }

}

و:


class Customer extends User

{

    public function getRole(): string

    {

        return 'customer';

    }

}

اکنون:


$admin = new Admin();



echo $admin->getRole();

خروجی:


admin


# کلاس فرزند باید تمام Abstract Methodها را پیاده‌سازی کند

اگر یک Abstract Class دارای چند Abstract Method باشد، کلاس فرزند باید آن‌ها را پیاده‌سازی کند؛ مگر اینکه خود کلاس فرزند نیز Abstract باشد.

مثلاً:


abstract class Report

{

    abstract public function generate(): string;



    abstract public function save(): bool;

}

کلاس زیر کامل است:


class PdfReport extends Report

{

    public function generate(): string

    {

        return 'PDF report';

    }



    public function save(): bool

    {

        return true;

    }

}

اما اگر یکی از متدها را پیاده‌سازی نکنیم:


class PdfReport extends Report

{

    public function generate(): string

    {

        return 'PDF report';

    }

}

کلاس PdfReport همچنان Abstract محسوب خواهد شد و نمی‌توان از آن Object معمولی ساخت.


# یک مثال واقعی‌تر: سیستم Notification

فرض کنید در یک پروژه می‌خواهیم سیستم ارسال اعلان ایجاد کنیم.

روش‌های ارسال اعلان می‌توانند شامل:

  • SMS
  • Email
  • Telegram
  • Push Notification

باشند.

می‌توانیم یک کلاس پایه داشته باشیم:


abstract class Notification

{

    public function __construct(

        protected string $message

    ) {

    }



    abstract public function send(string $recipient): bool;



    public function getMessage(): string

    {

        return $this->message;

    }

}

اکنون SMS:


class SmsNotification extends Notification

{

    public function send(string $recipient): bool

    {

        echo "Sending SMS to {$recipient}";



        return true;

    }

}

Email:


class EmailNotification extends Notification

{

    public function send(string $recipient): bool

    {

        echo "Sending Email to {$recipient}";



        return true;

    }

}

استفاده:


$sms = new SmsNotification('کد ورود شما 1234 است');



$sms->send('09120000000');

در این معماری، کلاس پایه مشخص می‌کند:

> هر Notification باید قابلیت send() داشته باشد.

اما نحوه ارسال را به کلاس‌های فرزند واگذار می‌کند.


# Abstract Class با Property

Abstract Class می‌تواند Property داشته باشد.

مثلاً:


abstract class Product

{

    protected string $name;



    protected float $price;



    public function __construct(

        string $name,

        float $price

    ) {

        $this->name = $name;

        $this->price = $price;

    }



    abstract public function calculatePrice(): float;

}

کلاس فرزند:


class PhysicalProduct extends Product

{

    public function calculatePrice(): float

    {

        return $this->price + 50000;

    }

}

و محصول دیجیتال:


class DigitalProduct extends Product

{

    public function calculatePrice(): float

    {

        return $this->price;

    }

}

در این مثال اطلاعات مشترک در کلاس پایه قرار گرفته است، اما محاسبه قیمت برای هر نوع محصول متفاوت است.


# Abstract Class با Constructor

یک Abstract Class می‌تواند Constructor داشته باشد.

مثلاً:


abstract class User

{

    protected string $name;



    public function __construct(string $name)

    {

        $this->name = $name;

    }



    abstract public function getRole(): string;

}

کلاس فرزند:


class Admin extends User

{

    public function getRole(): string

    {

        return 'admin';

    }

}

هنگام ایجاد Object:


$admin = new Admin('Saeed');

Constructor کلاس پایه نیز در زنجیره ساخت Object نقش دارد.

اگر کلاس فرزند Constructor خودش را تعریف کند و بخواهیم Constructor والد را اجرا کنیم، می‌توانیم از parent::__construct() استفاده کنیم:


class Admin extends User

{

    public function __construct(

        string $name,

        private string $department

    ) {

        parent::__construct($name);

    }



    public function getRole(): string

    {

        return 'admin';

    }

}


# Abstract Class و Encapsulation

Abstract Class می‌تواند برای پیاده‌سازی Encapsulation نیز استفاده شود.

مثلاً:


abstract class BankAccount

{

    protected float $balance = 0;



    public function deposit(float $amount): void

    {

        if ($amount <= 0) {

            throw new InvalidArgumentException(

                'Amount must be positive.'

            );

        }



        $this->balance += $amount;

    }



    public function getBalance(): float

    {

        return $this->balance;

    }



    abstract public function withdraw(float $amount): bool;

}

در اینجا:

  • منطق واریز در کلاس پایه قرار دارد.
  • موجودی در Property محافظت‌شده نگهداری می‌شود.
  • نحوه برداشت به کلاس‌های فرزند واگذار شده است.

# Abstract Class در معماری پروژه

یکی از کاربردهای مهم Abstract Class ایجاد یک Base Class برای چند پیاده‌سازی مختلف است.

مثلاً:


Payment

 ├── BankPayment

 ├── WalletPayment

 ├── PaypalPayment

 └── CryptoPayment

کلاس Payment رفتارهای عمومی را نگهداری می‌کند و کلاس‌های فرزند رفتار اختصاصی خودشان را دارند.

این ساختار باعث می‌شود کد پروژه منظم‌تر و قابل توسعه‌تر باشد.


# Abstract Class در PHP و Polymorphism

Abstract Class می‌تواند در کنار Polymorphism بسیار مفید باشد.

مثلاً:


abstract class Payment

{

    abstract public function pay(float $amount): bool;

}

دو پیاده‌سازی داریم:


class BankPayment extends Payment

{

    public function pay(float $amount): bool

    {

        echo "Bank payment";



        return true;

    }

}

و:


class WalletPayment extends Payment

{

    public function pay(float $amount): bool

    {

        echo "Wallet payment";



        return true;

    }

}

حالا می‌توانیم متدی داشته باشیم که با نوع Payment کار کند:


function processPayment(

    Payment $payment,

    float $amount

): bool {

    return $payment->pay($amount);

}

استفاده:


processPayment(

    new BankPayment(),

    500000

);



processPayment(

    new WalletPayment(),

    500000

);

متد processPayment() اهمیتی نمی‌دهد که Object مربوط به بانک است یا کیف پول.

فقط می‌داند که Object از Payment ارث‌بری کرده و متد pay() را دارد.

این یکی از کاربردهای مهم طراحی شی‌گراست.


# تفاوت Abstract Class و Class معمولی در PHP

یک Class معمولی می‌تواند مستقیماً Instantiate شود:


class User

{

}

می‌توانیم بنویسیم:


$user = new User();

اما برای Abstract Class این امکان وجود ندارد:


abstract class User

{

}

این کد خطا خواهد داد:


$user = new User();

تفاوت اصلی این است که Abstract Class برای استفاده به عنوان یک کلاس پایه طراحی می‌شود.


# تفاوت Abstract Class و Interface در PHP

این یکی از مهم‌ترین سؤالات هنگام یادگیری OOP در PHP است.

Interface بیشتر برای تعریف یک قرارداد استفاده می‌شود.

مثلاً:


interface PaymentInterface

{

    public function pay(float $amount): bool;

}

اما Abstract Class می‌تواند علاوه بر قرارداد، منطق مشترک نیز داشته باشد:


abstract class Payment

{

    protected string $currency = 'IRR';



    public function getCurrency(): string

    {

        return $this->currency;

    }



    abstract public function pay(float $amount): bool;

}

بنابراین به صورت ساده:

ویژگیAbstract ClassInterface
ساخت Object مستقیم❌❌
ارث‌بریextendsimplements
متد Abstract✅✅
متد دارای پیاده‌سازی✅در PHP مدرن Interface می‌تواند متدهای دارای پیاده‌سازی مشخصی مانند default نداشته باشد، اما می‌تواند public methodهای مشخص و همچنین static/private methodهای داخلی داشته باشد
Property معمولی✅ویژگی‌های ثابت/constant و امکانات مربوط به Interface
Constructor✅❌
استفاده برای منطق مشترک✅محدودتر
چندتایی بودنیک کلاس فقط از یک کلاس پایه ارث می‌بردیک کلاس می‌تواند چند Interface را implement کند

برای مثال:


abstract class Payment

{

    abstract public function pay(float $amount): bool;



    public function logPayment(): void

    {

        echo 'Payment logged';

    }

}

در اینجا هم قرارداد داریم و هم منطق مشترک.

اما Interface بیشتر برای مشخص کردن قابلیت مورد انتظار استفاده می‌شود.


# چه زمانی Abstract Class بهتر از Interface است؟

اگر چند کلاس:

  1. رفتار مشترک دارند
  2. Property مشترک دارند
  3. Constructor مشترک دارند
  4. منطق مشترک دارند
  5. و در عین حال بعضی رفتارها باید توسط فرزند پیاده‌سازی شوند

Abstract Class گزینه مناسبی است.

مثلاً:


abstract class FileStorage

{

    protected string $disk;



    public function __construct(string $disk)

    {

        $this->disk = $disk;

    }



    public function getDisk(): string

    {

        return $this->disk;

    }



    abstract public function upload(string $path): bool;

}

کلاس‌های مختلف می‌توانند از این ساختار استفاده کنند:


class LocalStorage extends FileStorage

{

    public function upload(string $path): bool

    {

        // upload to local storage



        return true;

    }

}

و:


class S3Storage extends FileStorage

{

    public function upload(string $path): bool

    {

        // upload to S3



        return true;

    }

}

این نوع معماری در پروژه‌های واقعی بسیار کاربردی است.


# Abstract Class در Laravel چه کاربردی دارد؟

در پروژه‌های Laravel نیز می‌توان از Abstract Class برای ایجاد ساختارهای قابل توسعه استفاده کرد.

فرض کنید یک سیستم پرداخت داریم.

می‌توانیم یک کلاس پایه ایجاد کنیم:


abstract class PaymentGateway

{

    public function __construct(

        protected string $apiKey

    ) {

    }



    abstract public function pay(

        int $amount

    ): bool;



    public function isConfigured(): bool

    {

        return !empty($this->apiKey);

    }

}

سپس درگاه‌های مختلف را ایجاد کنیم:


class ZarinpalGateway extends PaymentGateway

{

    public function pay(int $amount): bool

    {

        // Zarinpal API



        return true;

    }

}

یا:


class IDPayGateway extends PaymentGateway

{

    public function pay(int $amount): bool

    {

        // IDPay API



        return true;

    }

}

حالا منطق مشترک در PaymentGateway قرار گرفته و منطق اختصاصی هر درگاه در کلاس خودش قرار دارد.

این مدل معماری می‌تواند در پروژه‌هایی که چند Provider یا Driver دارند بسیار مفید باشد.


# Abstract Class یا Trait؟

Abstract Class و Trait هر دو می‌توانند به اشتراک‌گذاری کد کمک کنند، اما هدفشان یکی نیست.

Abstract Class معمولاً برای تعریف یک رابطه والد و فرزند استفاده می‌شود:


Payment

   ↓

BankPayment

اما Trait برای اشتراک‌گذاری قابلیت بین کلاس‌هایی استفاده می‌شود که الزاماً در یک سلسله‌مراتب ارث‌بری قرار ندارند.

مثلاً:


trait HasUuid

{

    public function generateUuid(): string

    {

        return uniqid();

    }

}

و می‌توان آن را در چند کلاس استفاده کرد:


class User

{

    use HasUuid;

}

و:


class Order

{

    use HasUuid;

}

پس نباید Abstract Class و Trait را جایگزین یکدیگر در نظر گرفت.


# Abstract Class و Inheritance

Abstract Class ارتباط مستقیمی با Inheritance دارد.

مثلاً:


abstract class Vehicle

{

    abstract public function start(): void;

}

و:


class Car extends Vehicle

{

    public function start(): void

    {

        echo 'Car started';

    }

}

در اینجا:


Vehicle

   ↓

Car

Car یک نوع Vehicle محسوب می‌شود و رفتار مورد نیاز کلاس پایه را پیاده‌سازی می‌کند.


# چند سطح Abstract Class

در PHP می‌توان چند سطح ارث‌بری نیز داشت.

مثلاً:


abstract class Vehicle

{

    abstract public function start(): void;

}

سپس:


abstract class Car extends Vehicle

{

    public function openDoor(): void

    {

        echo 'Door opened';

    }

}

و در نهایت:


class Tesla extends Car

{

    public function start(): void

    {

        echo 'Tesla started';

    }

}

در این ساختار:


Vehicle

   ↓

Car

   ↓

Tesla

کلاس Car خودش Abstract است و Tesla در نهایت تمام الزامات Abstract را پیاده‌سازی می‌کند.


# اشتباهات رایج هنگام استفاده از Abstract Class

1. تلاش برای ساخت Object از Abstract Class

این کار اشتباه است:


abstract class User

{

}



$user = new User();

Abstract Class مستقیماً Instantiate نمی‌شود.


2. پیاده‌سازی نکردن Abstract Method

اگر کلاس فرزند Abstract نباشد، باید Abstract Methodهای والد را پیاده‌سازی کند.

مثلاً:


abstract class Payment

{

    abstract public function pay();

}

این کلاس کامل نیست:


class BankPayment extends Payment

{

}

باید pay() را پیاده‌سازی کنیم.


3. استفاده بیش از حد از Abstract Class

هر کلاس پایه‌ای لازم نیست Abstract باشد.

اگر یک کلاس معمولی می‌تواند نیاز پروژه را برطرف کند، نباید صرفاً برای پیچیده‌تر کردن معماری از Abstract Class استفاده کنیم.


4. قرار دادن منطق بیش از حد در کلاس پایه

اگر Abstract Class بیش از حد بزرگ شود، تمام کلاس‌های فرزند به منطق‌های زیادی وابسته می‌شوند.

بهتر است کلاس پایه فقط رفتارهای واقعاً مشترک را نگهداری کند.


# بهترین روش استفاده از Abstract Class

هنگام طراحی Abstract Class چند نکته را در نظر بگیرید.

1. هدف کلاس پایه را مشخص کنید

قبل از ایجاد کلاس Abstract بپرسید:

> چه چیزی بین تمام کلاس‌های فرزند مشترک است؟


2. رفتارهای مشترک را در والد قرار دهید

مثلاً:


public function getCurrency(): string

{

    return $this->currency;

}


3. رفتارهای متفاوت را Abstract کنید

مثلاً:


abstract public function pay(float $amount): bool;


4. Abstract Class را بیش از حد بزرگ نکنید

اگر کلاس پایه ده‌ها متد و Property دارد، احتمالاً طراحی نیاز به بازنگری دارد.


5. در صورت نیاز از Interface نیز استفاده کنید

در پروژه‌های بزرگ ممکن است بهترین طراحی ترکیبی از:


Interface

+

Abstract Class

+

Concrete Classes

باشد.


# یک مثال کامل: سیستم ارسال فایل

برای جمع‌بندی، یک مثال نسبتاً واقعی ایجاد کنیم.

فرض کنید برنامه ما از چند نوع Storage پشتیبانی می‌کند.

کلاس پایه:


abstract class Storage

{

    public function __construct(

        protected string $directory

    ) {

    }



    public function getDirectory(): string

    {

        return $this->directory;

    }



    abstract public function upload(

        string $file

    ): bool;



    abstract public function delete(

        string $file

    ): bool;

}

Storage محلی:


class LocalStorage extends Storage

{

    public function upload(string $file): bool

    {

        echo "Uploading {$file} to {$this->directory}";



        return true;

    }



    public function delete(string $file): bool

    {

        echo "Deleting {$file}";



        return true;

    }

}

Storage ابری:


class CloudStorage extends Storage

{

    public function upload(string $file): bool

    {

        echo "Uploading {$file} to cloud";



        return true;

    }



    public function delete(string $file): bool

    {

        echo "Deleting {$file} from cloud";



        return true;

    }

}

استفاده:


$local = new LocalStorage('/storage/files');



$local->upload('photo.jpg');

و:


$cloud = new CloudStorage('/cloud/files');



$cloud->upload('photo.jpg');

در این مثال:

  • Storage ساختار پایه را مشخص می‌کند.
  • directory بین پیاده‌سازی‌ها مشترک است.
  • getDirectory() منطق مشترک دارد.
  • upload() و delete() توسط کلاس‌های فرزند پیاده‌سازی می‌شوند.
  • LocalStorage و CloudStorage جزئیات متفاوت خودشان را دارند.

این دقیقاً یکی از سناریوهایی است که Abstract Class می‌تواند معماری کد را تمیزتر کند.


# چه زمانی نباید از Abstract Class استفاده کنیم؟

Abstract Class همیشه بهترین گزینه نیست.

اگر فقط می‌خواهید یک قرارداد تعریف کنید:


interface PaymentInterface

{

    public function pay(float $amount): bool;

}

Interface معمولاً انتخاب مناسب‌تری است.

اگر فقط می‌خواهید چند متد یا قابلیت را بین کلاس‌های نامرتبط به اشتراک بگذارید، Trait ممکن است مناسب‌تر باشد.

اگر اصلاً نیاز به ارث‌بری ندارید، شاید یک Class معمولی، Service یا Composition انتخاب بهتری باشد.


# جمع‌بندی Abstract Class در PHP

Abstract Class در PHP ابزاری برای ایجاد کلاس‌های پایه‌ای است که نمی‌خواهیم مستقیماً از آن‌ها Object بسازیم.

یک Abstract Class می‌تواند شامل موارد زیر باشد:

  • Property
  • Constructor
  • متدهای معمولی
  • Abstract Method
  • Constant
  • منطق مشترک

کلاس‌های فرزند با استفاده از extends از Abstract Class ارث‌بری می‌کنند.

یکی از مهم‌ترین مزایای Abstract Class این است که می‌توانیم منطق مشترک را یک بار در کلاس پایه پیاده‌سازی کنیم و در عین حال، پیاده‌سازی رفتارهای متفاوت را به کلاس‌های فرزند واگذار کنیم.

به طور خلاصه:


Abstract Class

      ↓

منطق مشترک + رفتارهای اجباری

      ↓

Concrete Classes

      ↓

پیاده‌سازی جزئیات

اگر در حال یادگیری OOP در PHP هستید، بعد از یادگیری Abstract Class بهتر است تفاوت بین Abstract Class، Interface و Trait را به خوبی درک کنید؛ زیرا این سه مفهوم در طراحی معماری پروژه‌های PHP و Laravel کاربرد زیادی دارند.


# سوالات متداول درباره Abstract Class در PHP

Abstract Class در PHP چیست؟

Abstract Class یک کلاس پایه است که نمی‌توان مستقیماً از آن Object ایجاد کرد و معمولاً برای تعریف ساختار و منطق مشترک بین کلاس‌های فرزند استفاده می‌شود.

آیا از Abstract Class می‌توان Object ساخت؟

خیر. یک Abstract Class مستقیماً Instantiate نمی‌شود و باید از یک کلاس غیر Abstract که از آن ارث‌بری کرده است استفاده کنید.

Abstract Method در PHP چیست؟

Abstract Method متدی است که در کلاس Abstract فقط تعریف می‌شود و کلاس فرزند باید پیاده‌سازی آن را ارائه کند.

آیا Abstract Class می‌تواند متد معمولی داشته باشد؟

بله. برخلاف یک قرارداد صرف، Abstract Class می‌تواند هم Abstract Method و هم متدهای دارای پیاده‌سازی داشته باشد.

تفاوت Abstract Class و Interface چیست؟

Abstract Class می‌تواند علاوه بر تعریف رفتارهای اجباری، Property، Constructor و منطق مشترک داشته باشد. Interface بیشتر برای تعریف قرارداد و قابلیت مورد انتظار بین کلاس‌ها استفاده می‌شود.

تفاوت Abstract Class و Trait چیست؟

Abstract Class برای ایجاد رابطه والد و فرزند و تعریف یک ساختار پایه استفاده می‌شود، در حالی که Trait بیشتر برای اشتراک‌گذاری قابلیت و کد بین کلاس‌های مختلف کاربرد دارد.

آیا یک Abstract Class می‌تواند Constructor داشته باشد؟

بله. Abstract Class می‌تواند Constructor داشته باشد و کلاس‌های فرزند می‌توانند در صورت نیاز آن را از طریق parent::__construct() فراخوانی کنند.

آیا یک کلاس فرزند می‌تواند Abstract Method والد را پیاده‌سازی نکند؟

اگر خود کلاس فرزند نیز Abstract باشد، می‌تواند پیاده‌سازی آن را به کلاس‌های فرزند بعدی واگذار کند. اما یک کلاس معمولی باید Abstract Methodهای والد را پیاده‌سازی کند.


# مقالات مرتبط برای لینک‌سازی داخلی

برای تقویت ساختار Topic Cluster سایت سی ام اس نویس، این مقاله بهتر است به مقالات زیر لینک داخلی داشته باشد:

  1. Interface در PHP چیست؟
  2. Anchor پیشنهادی: آموزش Interface در PHP

  1. Trait در PHP چیست؟
  2. Anchor پیشنهادی: آموزش Trait در PHP

  1. Inheritance در PHP چیست؟
  2. Anchor پیشنهادی: آموزش Inheritance در PHP

  1. OOP در PHP چیست؟
  2. Anchor پیشنهادی: آموزش برنامه‌نویسی شی‌گرا در PHP

  1. Class و Object در PHP چیست؟
  2. Anchor پیشنهادی: آموزش Class و Object در PHP

  1. Dependency Injection در PHP
  2. Anchor پیشنهادی: Dependency Injection در PHP

  1. SOLID در PHP
  2. Anchor پیشنهادی: اصول SOLID در PHP

همچنین از همین مقاله یک لینک طبیعی به صفحه اصلی پیلار با انکرتکست «آموزش برنامه نویسی وب و PHP» قرار دهید.

ساختار پیشنهادی لینک داخلی


آموزش برنامه نویسی وب و PHP

│

└── آموزش PHP

    │

    └── OOP در PHP

        │

        ├── Class و Object

        ├── Inheritance

        ├── Interface

        ├── Trait

        ├── Abstract Class ← این مقاله

        ├── Dependency Injection

        ├── SOLID

        └── Design Pattern

این ساختار کمک می‌کند ارتباط معنایی بین مقالات OOP حفظ شود و هر مقاله نقش مشخصی در کلاستر داشته باشد.

نظرات (0)

نظرات پس از تأیید مدیر نمایش داده می‌شوند

هنوز نظری ثبت نشده است؛ اولین نفر باشید!

مقالات مرتبط

ساخت CMS با Laravel 12؛ آموزش ساخت سیستم مدیریت محتوا از صفر

ساخت CMS با Laravel 12؛ آموزش ساخت سیستم مدیریت محتوا از صفر

۲۴ دقیقه
ساخت فروشگاه اینترنتی با Laravel 12؛ آموزش پروژه‌محور از صفر تا طراحی هسته فروشگاه

ساخت فروشگاه اینترنتی با Laravel 12؛ آموزش پروژه‌محور از صفر تا طراحی هسته فروشگاه

۲۲ دقیقه
ساخت Marketplace با Laravel؛ آموزش طراحی فروشگاه چندفروشندگی

ساخت Marketplace با Laravel؛ آموزش طراحی فروشگاه چندفروشندگی

۲۲ دقیقه
مدیریت Queueهای سنگین در Laravel؛ آموزش پردازش کارهای طولانی

مدیریت Queueهای سنگین در Laravel؛ آموزش پردازش کارهای طولانی

۲۲ دقیقه