آموزش اینترفیس (Interface) در جاوا
در این آموزش از کتاب برخط جاوا (Java) خواهیم دید که، Interface در جاوا یک نوع مرجع می باشد، که شبیه به کلاس بوده و مجموعه ای از متدهای abstract می باشد. کلاس یک اینترفیس را پیاده سازی می کند، از این رو متدهای abstract آن را نیز ارث بری می کند.
همراه با متدهای abstract، اینترفیس ممکن است حاوی ثابت ها، متدهای پیشفرض، متدهای static و نوع های تودرتو نیز باشد. بدنه ی متد تنها برای متدهای پیشفرض و متدهای static وجود دارد.
نوشتن Interface شبیه به نوشتن یک کلاس است. ولی کلاس خصوصیات و رفتارهای یک شیء را توصیف میکند و اینترفیس حاوی رفتارهایی است که کلاس آن ها را پیاده سازی خواهد کرد.
کلاسی که اینترفیس را implements می کند، باید تمامی متدهای آن را پیاده سازی کند، مگر آن که کلاس به صورت abstract تعریف شده باشد.
یک Interface در موارد زیر شبیه به کلاس است:
- می تواند به تعداد دلخواه متد در خود داشته باشد.
- در یک فایل با پسوند ".java" نوشته می شود، و نام فایل نیز با نام آن یکی است.
- بایت کد اینترفیس در یک فایل .class ظاهر می شود.
- Interface ها در پکیج هایی قرار می گیرند، و فایل بایت کد متناسب با آن ها باید در ساختار فولدر بندی همسان با نام پکیج قرار بگیرد.
با این حال، اینترفیس تفاوت های بسیاری با کلاس دارد:
- شما نمی توانید یک Interface را مقدار دهی کنید.
- اینترفیس هیچ سازنده (Constructor) ای ندارد
- تمامی متدهای موجود در آن به صورت پیشفرض abstract می باشند.
- هیچ فیلد instance ای ندارد، و تمامی فیلدهای آن باید به صورت static و final تعریف شوند.
- توسط یک کلاس extends نمیشود، بلکه توسط یک کلاس implements می شود.
- می تواند چندین اینترفیس را extends کند.
تعریف Interface
برای تعریف از کلمه کلیدی interface استفاده می شود. در ادامه مثالی ساده از تعریف آن را نشان می دهیم
public interface MyInterface {
// Any number of final, static fields
// Any number of abstract method declarations
}
اینترفیس شامل خصوصیات زیر می باشد:
- به طور پیشفرض abstract می باشد. نیازی به استفاده از کلمه کلیدی abstract برای تعریف آن نیست.
- تمامی متدهای تعریف شده درون آن نیز به طور پیشفرض abstract می باشد، بنابراین در تعریف متد نیز نیازی به کلمه کلیدی abstract نیست.
- متدهای تعریف شده در آن به طور پیشفرض public می باشند.
پیاده سازی
وقتی یک کلاس، یک اینترفیس را implements می کند، اینگونه فرض کنید که کلاس قراردادی را امضا کرده است که و توافق کرده است که تمام رفتارهای تعریف شده در Interface را انجام دهد. اگر یک کلاس تمامی رفتارهای آن را انجام ندهد، آن کلاس می بایست به صورت abstract تعریف شود.
برای پیاده سازی در یک کلاس از کلمه کلیدی implements استفاده می شود. کلمه کلیدی implements بعد از تعریف کلاس استفاده می شود.
مثال:
/* 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
هنگام override متدها، قواعد زیر را باید رعایت کرد:
- exception های چک شده (checked exceptions) نباید در متدهای پیاده سازی شده تعریف شوند، به غیر از آنهایی که توسط متد اینترفیس تعریف شده اند.
- مشخصات متد از قبیل نام آن و پارامترهای ورودی و نوع داده بازگشتی آن باید هنگام override شدن رعایت شوند.
- کلاسی که اینترفیس را پیاده سازی کرده است می تواند abstract باشد، و در اینصورت اجباری در پیاده سازی تمام متدها نخواهد بود.
زمان پیاده سازی، قواعد زیر وجود خواهند داشت:
- یک کلاس می تواند بیشتر از یک اینترفیس را در یک زمان پیاده سازی کند.
- یک کلاس تنها می تواند از یک کلاس ارث بری کند، ولی می تواند به تعداد دلخواه اینترفیس را پیاده سازی کند.
- یک اینترفیس می تواند از یک Interface دیگر ارث بری کند، به همان صورتی که یک کلاس از کلاس دیگری ارث بری می کند.
ارث بری
مشابه ارث بری در کلاس، اینترفیس ها نیز می توانند از یکدیگر ارث بری کنند، کلمه کلیدی extends برای منظور استفاده می شود، و فرزند تمامی متدهای پدر خود را ارث بری می کند.
در کد زیر Hockey و Football از Sports ارث بری کرده اند:
// 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 دارای 4 متد می باشد، و همچنین دو این متد دیگر نیز از Sports به ارث بده است؛ بدینصورت، کلاسی که Hockey را پیاده سازی می کند، باید تمامی 6 متد را پیاده سازی کند. به همین ترتیب، کلاسی که Football را پیاده سازی می کند، باید 3 متد از Football و دو متد از Sports را پیاده سازی کند.
آموزش ارث بری چندگانه در Interface
کلاس ها در جاوا تنها می توانند یک کلاس پدر داشته باشند. ارث بری چندگانه برای کلاس ها مجاز نیست. اینترفیس ها کلاس نیستند، از این رو می توانند چندین پدر داشته باشد.
کلمه کلیدی extends یک بار نوشته می شود، و اینترفیس های پدر در ادامه آن با استفاده از جدا کننده ی کاما لیست می شوند.
برای مثال در صورتی که Hockey از Sports و Events ارث بری کند، به صورت زیر تعریف می شود:
public interface Hockey extends Sports, Event
اینترفیس های Tagging
یکی عمومی ترین استفاده های ارث بری در اینجا، زمانی است که پدر حاوی هیچ متدی نباشد. برای مثال MouseListener در پکیج java.awt.event از java.util.EventListener ارث بری می کند، که به صورت زیر تعریف شده است:
package java.util;
public interface EventListener
{}
این حالت را tagging می گویند. tagging دو کاربرد زیر را دارد:
ایجاد یک پدر مشترک - همانند EventListener، که توسط صدها اینترفیس دیگر در API جاوا ارث بری شده است، شما می توانید tagging را جهت ایجاد یک اینترفیس مشترک برای گروهی دیگر استفاده کنید. برای مثال، هنگامی که یک اینترفیس، EventListener را ارث بری می کند، JVM متوجه می شود که این مورد خاص برای یک استفاده ی رخدادی می باشد.
افزودن یک نوع داده برای یک کلاس - در این حالت کلاسی که tagging را پیاده سازی می کند، نیازی به تعریف متدها ندارد (چرا که هیچ متدی ندارد)، ولی کلاس در پلی مورفیسم یک نوع اینترفیسی خواهد بود.