فصل 21: اینترفیس (Interface) در جاوا و تفاوت آن با کلاس های انتزاعی

03 شهریور 1397
java-interfaces

اینترفیس در جاوا به گونه ای الگوی ساخت کلاس می باشد و شامل متدهای انتزاعی و ثابت های استاتیک می باشد. در واقع می توان گفت که اینترفیس مکانیزمی است که برای دستیبایی به انتزاع و وراثت چندگانه استفاده می شود. دقت کنید که تنها متدهای انتزاعی وجود دارد و متدها دارای بدنه نمی باشند.

اینترفیس هم همانند کلاس های انتزاعی امکان نمونه ساختن ازشان وجود ندارد و تنها می توان از آنها برای ساخت کلاس استفاده کرد در واقع یه رابطه IS-A دارند.

از جاوا 8، امکان وجود متدهای پیش فرض و استاتیک فراهم شده است و از جاوا 9 به بعد نیز امکان وجود متدهای خصوصی در اینترفیس (Interface) فراهم شده است.

دلایل استفاده از اینترفیس (Interface) در جاوا

سه دلیل عمده برای استفاده از اینترفیس (Interface) وجود دارد:

  1. دستیابی به انتزاع یا Abstraction
  2. با استفاده از اینترفیس (Interface) ، امکان استفاده از وراثت چندگانه فراهم می شود.
  3. برای کم کردن ارتباط میان اجزای برنامه استفاده میشود (Loose Coupling)

طرز تعریف یک اینترفیس (Interface) در جاوا

با استفاده از کلمه کلیدی Interface می توان یک اینترفیس ساخت. دقت کنید که متدهای موجود تنها انتزاعی می باشند و بدنه کد ندارند. همچنین تمام فیلدها عمومی، final و استاتیک می باشند. کلاسی که از یک اینترفیس استفاده می کند، باید تمام متدهای تعریف شده در اینترفیس را پیاده کند.

سینتکس:

interface <interface_name>{  
      
    // declare constant fields  
    // declare methods that abstract   
    // by default.  
}

دقت کنید که خود کامپایلر جزئیاتی را به برنامه ما اضافه می کند. به عنوان مثال تمام متدها عمومی و انتزاعی هستند و تمام فیلدها، عمومی و استاتیک و final.

اینترفیس یا روابط (Interface) در جاوا

رابطه میان کلاس و اینترفیس (Interface):

یک کلاس می تواند از کلاس دیگری ارث بری کند. یک اینترفیس (Interface) می تواند از یک اینترفیس دیگر ارث بری کند اما یک کلاس می تواند یک اینترفیس را پیاده سازی (Implement) کند.

مثال اینترفیس ها در جاوا

در مثال پایین، اینترفیس Printable دارای یک متد می باشد که در کلاس طرز کارش پیاده سازی شده است.

مثال:

interface printable{  
void print();  
}  
class A6 implements printable{  
public void print(){System.out.println("Hello");}  
  
public static void main(String args[]){  
A6 obj = new A6();  
obj.print();  
 }  
}

خروجی:

Hello

در مثال پایین، یک اینترفیس به نام Drawable داریم که در کلاس های Circle و Rectangle از آن استفاده شده است و متد draw در هر کدوم از کلاس ها پیاده سازی شده اند.

مثال:

//Interface declaration: by first user  
interface Drawable{  
void draw();  
}  
//Implementation: by second user  
class Rectangle implements Drawable{  
public void draw(){System.out.println("drawing rectangle");}  
}  
class Circle implements Drawable{  
public void draw(){System.out.println("drawing circle");}  
}  
//Using interface: by third user  
class TestInterface1{  
public static void main(String args[]){  
Drawable d=new Circle();//In real scenario, object is provided by method e.g. getDrawable()  
d.draw();  
}}

خروجی:

drawing circle

در مثال پایین یک اینترفیس بانک تعریف شده است که کلاسها آنرا پیاده سازی میکنند.

مثال:

interface Bank{  
float rateOfInterest();  
}  
class SBI implements Bank{  
public float rateOfInterest(){return 9.15f;}  
}  
class PNB implements Bank{  
public float rateOfInterest(){return 9.7f;}  
}  
class TestInterface2{  
public static void main(String[] args){  
Bank b=new SBI();  
System.out.println("ROI: "+b.rateOfInterest());  
}}

خروجی:

ROI: 9.15

ارث بری اینترفیس (Interface) در جاوا

وراثت چندگانه توسط اینترفیس (Interface)

در صورتی که یک کلاس چندین اینترفیس (Interface) را پیاده سازی کند و یا یک اینترفیس از چندین اینترفیس ارث بری کند، آنگاه وراثت چندگانه خواهیم داشت. نگاه کنید:

مثال:

interface Printable{  
void print();  
}  
interface Showable{  
void show();  
}  
class A7 implements Printable,Showable{  
public void print(){System.out.println("Hello");}  
public void show(){System.out.println("Welcome");}  
  
public static void main(String args[]){  
A7 obj = new A7();  
obj.print();  
obj.show();  
 }  
}

خروجی:

Output:Hello
       Welcome

سوال: چرا وراثت چندگانه توسط اینترفیس قابل انجام است اما از طریق کلاس نمی شود؟

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

مثال:

interface Printable{  
void print();  
}  
interface Showable{  
void print();  
}  
  
class TestInterface3 implements Printable, Showable{  
public void print(){System.out.println("Hello");}  
public static void main(String args[]){  
TestInterface3 obj = new TestInterface3();  
obj.print();  
 }  
}

خروجی:

Hello

در مثال بالا، دو اینترفیس دارای متد یکسانی می باشند اما از آنجایی که پیاده سازی آن توسط خود کلاس صورت گرفته است، ابهامی وجود ندارد.

وراثت در اینترفیس (Interface)

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

مثال:

interface Printable{  
void print();  
}  
interface Showable extends Printable{  
void show();  
}  
class TestInterface4 implements Showable{  
public void print(){System.out.println("Hello");}  
public void show(){System.out.println("Welcome");}  
  
public static void main(String args[]){  
TestInterface4 obj = new TestInterface4();  
obj.print();  
obj.show();  
 }  
}

خروجی:

Hello
Welcome

متد پیش فرض (default) در جاوا 8

همانطور که گفته شد، از جاوا 8 به بعد، امکان پشتیبانی از متد default فراهم شد. به مثال دقت کنید:

مثال:

interface Drawable{  
void draw();  
default void msg(){System.out.println("default method");}  
}  
class Rectangle implements Drawable{  
public void draw(){System.out.println("drawing rectangle");}  
}  
class TestInterfaceDefault{  
public static void main(String args[]){  
Drawable d=new Rectangle();  
d.draw();  
d.msg();  
}}

خروجی:

drawing rectangle
default method

متد استاتیک در اینترفیس (Interface)

به مثال زیر با دقت نگاه کنید:

مثال:

interface Drawable{  
void draw();  
static int cube(int x){return x*x*x;}  
}  
class Rectangle implements Drawable{  
public void draw(){System.out.println("drawing rectangle");}  
}  
  
class TestInterfaceStatic{  
public static void main(String args[]){  
Drawable d=new Rectangle();  
d.draw();  
System.out.println(Drawable.cube(3));  
}}

خروجی:

drawing rectangle
27

سوال: اینترفیس برچسب‌دار چیست؟

به اینترفیسی که دارای عضوی نمی باشد یک اینترفیس برچسب‌دار (Tagged or marker) می گوییم. از معروف ترین اینترفیس های این شکلی می توان به Serializable، Cloneable یا Remote اشاره کرد. اینترفیس‌های برچسب‌دار با فراهم کردن اطلاعاتی مفید برای JVM، امکان انجام عملیات‌هایی را برای ماشین مجازی جاوا فراهم می کند.

//How Serializable interface is written?  
public interface Serializable{  
}

اینترفیس (Interface) داخلی در جاوا

یک اینترفیس می تواند در داخل خود از یک اینترفیس دیگر استفاده کند. برای مثال:

مثال:

interface printable{  
 void print();  
 interface MessagePrintable{  
   void msg();  
 }  
}

تفاوت بین اینترفیس (Interface) و کلاس انتزاعی

در حالی که اینترفیس و کلاس انتزاعی هر دو برای دستیابی به انتزاع مورد استفاده قرار می گیرند و امکان تعریف متدهای انتزاعی در هر دو وجود دارد  و از هر دو نمی توان نمونه ساخت، تفاوت هایی هم بین این دو مفهوم وجود دارد که بررسی می کنیم.

کلاس انتزاعی اینترفیس (Interface) 
امکان وجود متدهای انتزاعی و غیر انتزاعی وجود دارد. اینترفیس تنها می تواند کلاس انتزاعی داشته باشد (از جاوا 8 به بعد، متد دیفالت و استاتیک هم می تواند داشته باشد)
از وراثت چندگانه پشتیبانی نمی کند. از وراثت چندگانه پشتیبانی می کند.
می تواند فیلدهای  final غیر final ، استاتیک و غیر استاتیک داشته باشد. تنها فیلد استاتیک و final دارد
می تواند پیاده سازی یک اینترفیس را بر عهده بگیرد نمی تواند پیاده سازی یک کلاس انتزاعی را بر عهده گیرد
از کلیدواژه  abstract برای تعریف خود استفاده میکند. از کلیدواژه  interface  برای تعریف خود استفاده میکند.
می تواند از کلاس های دیگر ارث بری کند و چندین اینترفیس را پیاده سازی کند. تنها می تواند از اینترفیس های دیگر ارث بری کند.
برای ارث بری از کلاس انتزاعی از کلیدواژه extends استفاده می شود. برای پیاده سازی یک اینترفیس از implements استفاده می شود.
اعضای کلاس انتزاغی می توانند خصوصی یا protected باشد به طور پیش فرض تنها عمومی میباشد.
مثال:
public abstract class Shape{
public abstract void draw();
}
مثال:
public interface Drawable{
void draw();
}

به طور خلاصه انتزاع در اینترفیس 100 درصد است در حالی که در کلاس های انتزاعی بین 0 تا 100 درصد است.

در مثال زیر می توانید تفاوت بین کلاس انتزاعی و اینترفیس (Interface) را بهتر ببینید:

ورودی:

//Creating interface that has 4 methods  
interface A{  
void a();//bydefault, public and abstract  
void b();  
void c();  
void d();  
}  
  
//Creating abstract class that provides the implementation of one method of A interface  
abstract class B implements A{  
public void c(){System.out.println("I am C");}  
}  
  
//Creating subclass of abstract class, now we need to provide the implementation of rest of the methods  
class M extends B{  
public void a(){System.out.println("I am a");}  
public void b(){System.out.println("I am b");}  
public void d(){System.out.println("I am d");}  
}  
  
//Creating a test class that calls the methods of A interface  
class Test5{  
public static void main(String args[]){  
A a=new M();  
a.a();  
a.b();  
a.c();  
a.d();  
}}

خروجی:

I am a
       I am b
       I am c
       I am d
نویسنده شوید
دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

قلی پشمالو
17 آذر 1398
اینم منبعش https://www.javatpoint.com/interface-in-java در ضمن اون ساعتی رو هم که توی نظرات زدی با ساعت ملی سه ساعت اختلاف داره دقت رو عشق است

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

قلی پشمالو
17 آذر 1398
سلام اول دم شما گرم که این مفاهیم رو نوشتی دم شما گرم که ترجمه کردی فقط خواهشاً مطالب رو که ترجمه می کنی لطفاً منبع رو هم اعلام کن که ملت گیج نزنن سپاس

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.