شنبه ۲۹ دي ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش جاوا - رابط ها

یک رابط (Interface) یک نوع مرجع در جاوا است. این مانند یک کلاس است و مجموعه‌ای از متدهای انتزاعی (Abstract) می‌باشد. یک کلاس یک رابط را پیاده‌سازی می‌کند و از این طریق متدهای انتزاعی رابط را به ارث می‌برد.

علاوه بر متدهای انتزاعی، یک رابط ممکن است شامل ثابت‌ها (Constants)، متدهای پیش‌فرض (Default Methods)، متدهای استاتیک (Static Methods) و نوع‌های تو در تو (Nested Types) باشد. بدنه متدها فقط برای متدهای پیش‌فرض و متدهای استاتیک وجود دارد.

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

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

یک رابط مشابه یک کلاس به صورت زیر است:

  • یک رابط می‌تواند حاوی هر تعدادی متد باشد.

  • یک رابط در یک فایل با پسوند .java نوشته می‌شود و نام رابط با نام فایل مطابقت دارد.

  • بایت کد یک رابط در یک فایل .class ظاهر می‌شود.

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

با این حال، یک رابط در چندین جهت با یک کلاس متفاوت است، شامل موارد زیر −

  • شما نمی‌توانید یک رابط را نمونه‌گیری کنید.

  • یک رابط حاوی سازنده‌ای نیست.

  • تمامی متدهای یک رابط انتزاعی هستند.

  • یک رابط نمی‌تواند شامل فیلدهای نمونه باشد. تنها فیلدهای قابل قبول در یک رابط، باید به صورت همزمان و نهایی (Static and Final) تعریف شوند.

  • یک کلاس رابط را گسترش نمی‌دهد، بلکه یک کلاس رابط را پیاده‌سازی می‌کند.

  • یک رابط می‌تواند چندین رابط را گسترش دهد.

تعریف رابط‌ها

کلمه کلیدی interface برای تعریف رابط استفاده می‌شود. در ادامه یک مثال ساده برای تعریف رابط آورده شده است −

مثال

در ادامه یک مثال از یک رابط آورده شده است −


/* File name : NameOfInterface.java */
import java.lang.*;
// Any number of import statements

public interface NameOfInterface {
   // Any number of final, static fields
   // Any number of abstract method declarations\
}

رابط‌ها (Interfaces) ویژگی‌های زیر را دارا می‌باشند −

  • یک رابط به صورت ضمنی انتزاعی (Abstract) است. شما نیازی به استفاده از کلمه کلیدی abstract در تعریف یک رابط ندارید.

  • هر متد در یک رابط نیز به صورت ضمنی انتزاعی است، بنابراین کلمه کلیدی abstract نیاز نیست.

  • متدهای یک رابط به صورت ضمنی عمومی (Public) هستند.

مثال


/* File name : Animal.java */
interface Animal {
   public void eat();
   public void travel();
}

پیاده‌سازی رابط‌ها

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

یک کلاس از کلمه کلیدی implements برای پیاده‌سازی یک رابط استفاده می‌کند. کلمه کلیدی implements در تعریف کلاس پس از بخش extends ظاهر می‌شود.

مثال


/* File name : MammalInt.java */
public class MammalInt implements Animal {

   public void eat() {
      System.out.println("Mammal eats");
   }

   public void travel() {
      System.out.println("Mammal travels");
   } 

   public int noOfLegs() {
      return 0;
   }

   public static void main(String args[]) {
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 

این عملیات نتیجه زیر را تولید خواهد کرد −

خروجی


Mammal eats
Mammal travels

هنگامی که متدهای تعریف شده در رابط‌ها را بازنویسی می‌کنید، باید چندین قانون را رعایت کنید −

  • استثنائات بررسی شده نباید در متدهای پیاده‌سازی شده به جز متدهایی که توسط متد رابط تعریف شده است یا زیر کلاس‌های آن تعریف شده باشند، اعلام شود.

  • امضای متد رابط و همچنین نوع بازگشتی یا زیرنوع آن باید در هنگام بازنویسی متدها حفظ شود.

  • یک کلاس پیاده‌سازی خود می‌تواند انتزاعی باشد و در این صورت، نیازی به پیاده‌سازی متدهای رابط نیست.

در هنگام پیاده‌سازی رابط‌ها، چندین قانون وجود دارد −

  • یک کلاس می‌تواند همزمان چندین رابط را پیاده‌سازی کند.

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

  • یک رابط می‌تواند رابط دیگری را گسترش دهد، به همان روشی که یک کلاس می‌تواند کلاس دیگری را گسترش دهد.

گسترش رابط‌ها

یک رابط می‌تواند رابط دیگری را به همان روشی که یک کلاس می‌تواند کلاس دیگری را گسترش دهد، گسترش دهد. برای گسترش یک رابط از کلمه کلیدی extends استفاده می‌شود و رابط فرزند متدهای رابط والدین را به ارث می‌برد.

رابط Sports زیر توسط رابط‌های Hockey و Football گسترش داده شده است.

مثال


// Filename: Sports.java
public interface Sports {
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// Filename: Football.java
public interface Football extends Sports {
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// Filename: Hockey.java
public interface Hockey extends Sports {
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

رابط Hockey شامل چهار متد است، اما دو متد را از رابط Sports به ارث می‌برد؛ بنابراین، یک کلاس که Hockey را پیاده‌سازی می‌کند، باید همه شش متد را پیاده‌سازی کند. به همین ترتیب، یک کلاس که Football را پیاده‌سازی می‌کند، باید سه متد از رابط Football و دو متد از رابط Sports را تعریف کند.

گسترش چندین رابط

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

کلمه کلیدی extends یک بار استفاده می‌شود و رابط‌های والد در یک لیست جداشده با کاما اعلام می‌شوند.

برای مثال، اگر رابط Hockey همزمان Sports و Event را گسترش می‌داد، به صورت زیر اعلام می‌شد −

مثال


public interface Hockey extends Sports, Event

رابط‌های برچسب‌گذاری (Tagging Interfaces)

معمول‌ترین استفاده از گسترش رابط‌ها زمانی رخ می‌دهد که رابط والد شامل هیچ متدی نباشد. به عنوان مثال، رابط MouseListener در بسته java.awt.event از رابط java.util.EventListener گسترش می‌یابد، که به شکل زیر تعریف شده است −

مثال


package java.util;
public interface EventListener
{}

یک رابط که هیچ متدی در آن وجود ندارد، به عنوان یک رابط برچسب‌گذاری شناخته می‌شود. دو هدف طراحی اساسی از رابط‌های برچسب‌گذاری وجود دارد −

ایجاد یک والد مشترک − همانند رابط EventListener که توسط ده‌ها رابط دیگر در API جاوا گسترش می‌یابد، می‌توانید از یک رابط برچسب‌گذاری برای ایجاد یک والد مشترک بین یک گروه از رابط‌ها استفاده کنید. به عنوان مثال، وقتی یک رابط از EventListener گسترش می‌یابد، JVM می‌داند که این رابط خاص در یک سناریوی انتقال رویداد استفاده خواهد شد.

اضافه کردن نوع داده به یک کلاس − این وضعیت مبدأ کلمه برچسب‌گذاری است. یک کلاس که یک رابط برچسب‌گذاری را پیاده‌سازی می‌کند، نیازی به تعریف هرگونه متد ندارد (زیرا رابط هیچ متدی ندارد)، اما کلاس از طریق چندریختی به یک نوع رابط تبدیل می‌شود.