Published on

تفاوت کلاس انتزاعی و اینترفیس در جاوا

نویسندگان

تفاوت کلاس انتزاعی و اینترفیس در جاوا

کلاس انتزاعی (Abstract Class) و اینترفیس (Interface) دو روش برای پیاده‌سازی انتزاع (Abstraction) در جاوا هستند. هرچند که هر دو برای تعریف رفتار مشترک در کلاس‌ها به کار می‌روند، اما تفاوت‌های زیادی در نحوه عملکرد و استفاده آنها وجود دارد.


1. کلاس انتزاعی (Abstract Class)

یک کلاس انتزاعی کلاسی است که نمی‌توان از آن نمونه‌سازی (Instance) کرد و می‌تواند شامل متدهای انتزاعی (بدون پیاده‌سازی) و متدهای معمولی (با پیاده‌سازی) باشد.

ویژگی‌های کلیدی:

  • ارث‌بری (Inheritance): یک کلاس دیگر می‌تواند از کلاس انتزاعی ارث‌بری کند.
  • متدها: می‌تواند شامل ترکیبی از متدهای انتزاعی و معمولی باشد.
  • سازنده‌ها (Constructors): می‌تواند سازنده داشته باشد.
  • متغیرها: می‌تواند شامل متغیرهای استاتیک، نهایی (Final) و معمولی باشد.
  • محدودیت در ارث‌بری: یک کلاس تنها می‌تواند از یک کلاس انتزاعی ارث‌بری کند (به دلیل تک‌ارث‌بری در جاوا).

نحو:

abstract class Animal {
    String name; // متغیر

    // سازنده
    Animal(String name) {
        this.name = name;
    }

    // متد انتزاعی
    abstract void sound();

    // متد معمولی
    void eat() {
        System.out.println(name + " در حال غذا خوردن است.");
    }
}

مثال:

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    @Override
    void sound() {
        System.out.println(name + " پارس می‌کند.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("بادی");
        dog.sound(); // بادی پارس می‌کند.
        dog.eat();   // بادی در حال غذا خوردن است.
    }
}

2. اینترفیس (Interface)

اینترفیس یک قرارداد است که مشخص می‌کند یک کلاس چه کاری باید انجام دهد، اما نحوه انجام آن را تعیین نمی‌کند. تا قبل از جاوا 8، تمامی متدهای اینترفیس انتزاعی بودند، اما از جاوا 8 به بعد، می‌توان متدهای پیش‌فرض (Default) و استاتیک نیز در آن تعریف کرد.

ویژگی‌های کلیدی:

  • پیاده‌سازی (Implementation): یک کلاس می‌تواند یک یا چند اینترفیس را پیاده‌سازی کند.
  • متدها:
    • همه متدها به‌صورت پیش‌فرض انتزاعی و عمومی هستند (تا قبل از جاوا 8).
    • از جاوا 8 به بعد:
      • متدهای پیش‌فرض (با پیاده‌سازی) و استاتیک مجاز هستند.
    • از جاوا 9 به بعد:
      • متدهای خصوصی نیز می‌توانند وجود داشته باشند.
  • متغیرها: فقط متغیرهای عمومی، استاتیک و نهایی مجاز هستند.
  • چندگانه‌ارث‌بری (Multiple Inheritance): یک کلاس می‌تواند چندین اینترفیس را پیاده‌سازی کند.
  • عدم وجود سازنده: اینترفیس نمی‌تواند سازنده داشته باشد.

نحو:

interface Animal {
    void sound(); // متد انتزاعی (پیش‌فرض عمومی و انتزاعی است)

    // متد پیش‌فرض
    default void eat() {
        System.out.println("حیوان در حال غذا خوردن است.");
    }

    // متد استاتیک
    static void sleep() {
        System.out.println("حیوان در حال خوابیدن است.");
    }
}

مثال:

class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("سگ پارس می‌کند.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();  // سگ پارس می‌کند.
        dog.eat();    // حیوان در حال غذا خوردن است.
        Animal.sleep(); // حیوان در حال خوابیدن است. (متد استاتیک)
    }
}

جدول مقایسه

ویژگیکلاس انتزاعیاینترفیس
نمونه‌سازینمی‌توان نمونه‌سازی کردنمی‌توان نمونه‌سازی کرد
ارث‌بری/پیاده‌سازیکلاس دیگر باید از آن ارث‌بری کند (تک‌ارث‌بری).کلاس دیگر می‌تواند آن را پیاده‌سازی کند (چندگانه‌ارث‌بری).
متدهامی‌تواند ترکیبی از متدهای انتزاعی و معمولی داشته باشد.متدها به‌صورت پیش‌فرض انتزاعی هستند (جاوا 8+ شامل متد پیش‌فرض و استاتیک).
سازنده‌ها (Constructors)می‌تواند سازنده داشته باشد.نمی‌تواند سازنده داشته باشد.
متغیرها (Variables)می‌تواند هر نوع متغیری داشته باشد.فقط متغیرهای عمومی، استاتیک و نهایی.
محدودیت ارث‌برییک کلاس فقط می‌تواند از یک کلاس انتزاعی ارث‌بری کند.یک کلاس می‌تواند چندین اینترفیس را پیاده‌سازی کند.
کاربردبرای به اشتراک‌گذاری رفتار و حالت (State) بین کلاس‌های مرتبط.برای تعریف قرارداد و پیاده‌سازی در کلاس‌های غیرمرتبط.

چه زمانی از هرکدام استفاده کنیم؟

  • کلاس انتزاعی:

    • زمانی که نیاز به به‌اشتراک‌گذاری رفتار یا وضعیت (State) بین کلاس‌های مرتبط دارید.
    • زمانی که ترکیبی از متدهای انتزاعی و معمولی نیاز دارید.
    • زمانی که نیاز به متغیرها یا متدهای protected یا private دارید.
  • اینترفیس:

    • زمانی که نیاز به تعریف قرارداد (Contract) دارید بدون تعیین نحوه پیاده‌سازی.
    • زمانی که می‌خواهید یک کلاس، رفتارهای مختلفی از اینترفیس‌های مختلف به ارث ببرد.
    • زمانی که نیاز به چندگانه‌ارث‌بری دارید.

مثال ترکیبی از کلاس انتزاعی و اینترفیس

interface Animal {
    void sound();
    default void eat() {
        System.out.println("حیوان در حال غذا خوردن است.");
    }
}

abstract class Mammal {
    void walk() {
        System.out.println("پستاندار در حال راه رفتن است.");
    }
}

class Dog extends Mammal implements Animal {
    @Override
    public void sound() {
        System.out.println("سگ پارس می‌کند.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.walk();  // پستاندار در حال راه رفتن است.
        dog.sound(); // سگ پارس می‌کند.
        dog.eat();   // حیوان در حال غذا خوردن است.
    }
}

این مثال نشان می‌دهد که چگونه می‌توان از ترکیب کلاس‌های انتزاعی و اینترفیس‌ها برای طراحی سیستم‌های پیچیده‌تر استفاده کرد.