جاوا

جلسه ۴۱: متدهای پیش فرض در اینترفیس ها در جاوا

interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
در این جلسه متدهای پیش فرض را معرفی کردیم و نحوه استفاده از آنها و کاربرد آنها را مشاهده کردید. در جلسه بعدی ، با متدهای استاتیک در اینترفیس ها آشنا خواهید شد.
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
کلاس فوق به دلیل مشکل Diamond در جاوا کامپایل نخواهد شد. برای حل مشکل کامپایل نشدن ، باید متد ()printSomething را به صورت زیر پیاده سازی کنیم:
public class Main implements InterfaceA, InterfaceB {

    @Override
    public void printSomething() {

        //Option 1 -> Provide our own implementation.
        System.out.println("I am inside Main class");

        //Option 2 -> Use existing implementation from interfaceA or interfaceB or both.
        InterfaceA.super.printSomething();
        InterfaceB.super.printSomething();
    }

    public static void main(String args[]){
         Main main = new Main();
         main.printSomething();
    }
}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
در این جلسه متدهای پیش فرض را معرفی کردیم و نحوه استفاده از آنها و کاربرد آنها را مشاهده کردید. در جلسه بعدی ، با متدهای استاتیک در اینترفیس ها آشنا خواهید شد.
public interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}

اینترفیس InterfaceB:

public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
حال ما یک کلاس Main تعریف خواهیم کرد که هر دو این اینترفیس ها را پیاده سازی کند. قبل از ادامه کار ، می خواهم در مورد سوالات زیر فکر کنید:
  1. آیا لازم است که متد ()printSomething را در کلاس Main پیاده سازی کنیم؟ اگر ما این کار را نکنیم آیا کلاس کامپایل می شود؟
  2. اگر شی از جنس کلاس Main داشته باشیم و متد ()printSomething را از این شی فراخوانی کنیم ، کدام پیاده سازی فراخوانی می شود؟ آیا متد تعریف شده در InterfaceA فراخوانی می شود یا متد تعریف شده در InterfaceB فراخوانی می شود؟
قبل از اینکه به این سوالات پاسخ دهم ، اجازه دهید کلاس Main را ایجاد کنیم که هر دو اینترفیس را پیاده سازی می کند.
public class Main implements InterfaceA, InterfaceB {

}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
کلاس فوق به دلیل مشکل Diamond در جاوا کامپایل نخواهد شد. برای حل مشکل کامپایل نشدن ، باید متد ()printSomething را به صورت زیر پیاده سازی کنیم:
public class Main implements InterfaceA, InterfaceB {

    @Override
    public void printSomething() {

        //Option 1 -> Provide our own implementation.
        System.out.println("I am inside Main class");

        //Option 2 -> Use existing implementation from interfaceA or interfaceB or both.
        InterfaceA.super.printSomething();
        InterfaceB.super.printSomething();
    }

    public static void main(String args[]){
         Main main = new Main();
         main.printSomething();
    }
}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
در این جلسه متدهای پیش فرض را معرفی کردیم و نحوه استفاده از آنها و کاربرد آنها را مشاهده کردید. در جلسه بعدی ، با متدهای استاتیک در اینترفیس ها آشنا خواهید شد.
public interface Vehicle {

    void cleanVehicle();

    default void startVehicle() {
        System.out.println("Vehicle is starting");
    }
}
همانطور که در بالا نشان داده شده است ، کلاس ما فقط باید متد انتزاعی را پیاده سازی کند. هنگامی که ما متد پیش فرض را فراخوانی می کنیم ، کدی که در اینترفیس تعریف شده اجرا می شود.

نحوه حل مشکلات ایجاد شده به دلیل متدهای پیش فرض

اگرچه معرفی متدهای پیش فرض بروزرسانی بسیار خوبی برای جاوا بود و توسعه را بسیار آسان کرد ، اما آنها یک نکته احتیاطی دارند که باید هنگام کد نویسی مورد توجه قرار گیرد. برای دیدن این نکته ، به یک مثال نگاه می کنیم. در اینجا ، ما دو اینترفیس با یک متد پیش فرض همنام ، یعنی ()printSomething داریم.

اینترفیس InterfaceA:

public interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}

اینترفیس InterfaceB:

public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
حال ما یک کلاس Main تعریف خواهیم کرد که هر دو این اینترفیس ها را پیاده سازی کند. قبل از ادامه کار ، می خواهم در مورد سوالات زیر فکر کنید:
  1. آیا لازم است که متد ()printSomething را در کلاس Main پیاده سازی کنیم؟ اگر ما این کار را نکنیم آیا کلاس کامپایل می شود؟
  2. اگر شی از جنس کلاس Main داشته باشیم و متد ()printSomething را از این شی فراخوانی کنیم ، کدام پیاده سازی فراخوانی می شود؟ آیا متد تعریف شده در InterfaceA فراخوانی می شود یا متد تعریف شده در InterfaceB فراخوانی می شود؟
قبل از اینکه به این سوالات پاسخ دهم ، اجازه دهید کلاس Main را ایجاد کنیم که هر دو اینترفیس را پیاده سازی می کند.
public class Main implements InterfaceA, InterfaceB {

}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
کلاس فوق به دلیل مشکل Diamond در جاوا کامپایل نخواهد شد. برای حل مشکل کامپایل نشدن ، باید متد ()printSomething را به صورت زیر پیاده سازی کنیم:
public class Main implements InterfaceA, InterfaceB {

    @Override
    public void printSomething() {

        //Option 1 -> Provide our own implementation.
        System.out.println("I am inside Main class");

        //Option 2 -> Use existing implementation from interfaceA or interfaceB or both.
        InterfaceA.super.printSomething();
        InterfaceB.super.printSomething();
    }

    public static void main(String args[]){
         Main main = new Main();
         main.printSomething();
    }
}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
در این جلسه متدهای پیش فرض را معرفی کردیم و نحوه استفاده از آنها و کاربرد آنها را مشاهده کردید. در جلسه بعدی ، با متدهای استاتیک در اینترفیس ها آشنا خواهید شد.
public interface Vehicle {

    void cleanVehicle();

    default void startVehicle() {
        System.out.println("Vehicle is starting");
    }
}
همانطور که در بالا نشان داده شده است ، کلاس ما فقط باید متد انتزاعی را پیاده سازی کند. هنگامی که ما متد پیش فرض را فراخوانی می کنیم ، کدی که در اینترفیس تعریف شده اجرا می شود.

نحوه حل مشکلات ایجاد شده به دلیل متدهای پیش فرض

اگرچه معرفی متدهای پیش فرض بروزرسانی بسیار خوبی برای جاوا بود و توسعه را بسیار آسان کرد ، اما آنها یک نکته احتیاطی دارند که باید هنگام کد نویسی مورد توجه قرار گیرد. برای دیدن این نکته ، به یک مثال نگاه می کنیم. در اینجا ، ما دو اینترفیس با یک متد پیش فرض همنام ، یعنی ()printSomething داریم.

اینترفیس InterfaceA:

public interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}

اینترفیس InterfaceB:

public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
حال ما یک کلاس Main تعریف خواهیم کرد که هر دو این اینترفیس ها را پیاده سازی کند. قبل از ادامه کار ، می خواهم در مورد سوالات زیر فکر کنید:
  1. آیا لازم است که متد ()printSomething را در کلاس Main پیاده سازی کنیم؟ اگر ما این کار را نکنیم آیا کلاس کامپایل می شود؟
  2. اگر شی از جنس کلاس Main داشته باشیم و متد ()printSomething را از این شی فراخوانی کنیم ، کدام پیاده سازی فراخوانی می شود؟ آیا متد تعریف شده در InterfaceA فراخوانی می شود یا متد تعریف شده در InterfaceB فراخوانی می شود؟
قبل از اینکه به این سوالات پاسخ دهم ، اجازه دهید کلاس Main را ایجاد کنیم که هر دو اینترفیس را پیاده سازی می کند.
public class Main implements InterfaceA, InterfaceB {

}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
کلاس فوق به دلیل مشکل Diamond در جاوا کامپایل نخواهد شد. برای حل مشکل کامپایل نشدن ، باید متد ()printSomething را به صورت زیر پیاده سازی کنیم:
public class Main implements InterfaceA, InterfaceB {

    @Override
    public void printSomething() {

        //Option 1 -> Provide our own implementation.
        System.out.println("I am inside Main class");

        //Option 2 -> Use existing implementation from interfaceA or interfaceB or both.
        InterfaceA.super.printSomething();
        InterfaceB.super.printSomething();
    }

    public static void main(String args[]){
         Main main = new Main();
         main.printSomething();
    }
}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
در این جلسه متدهای پیش فرض را معرفی کردیم و نحوه استفاده از آنها و کاربرد آنها را مشاهده کردید. در جلسه بعدی ، با متدهای استاتیک در اینترفیس ها آشنا خواهید شد.در این جلسه می آموزید که متدهای پیش فرض در اینترفیس ها چه هستند و چرا آنها در جاوا ۸ معرفی شده اند. موارد زیر را بیان خواهیم کرد:
  • متد پیش فرض چیست؟
  • سینتکس متدهای پیش فرض
  • نحوه حل مشکلات ایجاد شده به دلیل متدهای پیش فرض

متد پیش فرض چیست؟

قبل از جاوا ۸ ، فقط می توانستیم متدهای انتزاعی را در یک اینترفیس اعلام کنیم. اما ، جاوا ۸ مفهوم متدهای پیش فرض را معرفی کرد. متدهای پیش فرض متدهایی هستند که می توانند دارای بدنه باشند. مهمترین کاربرد متدهای پیش فرض در اینترفیس ها ، امکان ارائه قابلیتهای اضافی برای یک نوع خاص بدون نیاز به تغییر در کلاسهای مشتق شده است. قبل از جاوا ۸ ، اگر متد جدیدی در اینترفیس معرفی می شد ، تمام کلاس هایی که این اینترفیس را پیاده سازی می کردند دچار خطا می شدند و برای کامپایل شدن کد باید آن متد جدید را در همه کلاسهای مشتق شده ، پیاده سازی می کردیم. با این وجود ، گاهی اوقات متدها فقط یک پیاده سازی یکسان نیاز دارند و نیازی به ارائه پیاده سازی آنها در هر کلاس نیست. در این صورت ، می توانیم آن متد را به عنوان یک متد پیش فرض در اینترفیس اعلام کنیم و پیاده سازی آن را در خود اینترفیس ارائه دهیم.

سینتکس متدهای پیش فرض

syntax متد های پیش فرض را از طریق یک مثال نشان می دهیم. در اینجا ، ما یک اینترفیس با یک متد انتزاعی و یک متد پیش فرض داریم:
public interface Vehicle {

    void cleanVehicle();

    default void startVehicle() {
        System.out.println("Vehicle is starting");
    }
}
اکنون یک کلاس ایجاد می کنیم که اینترفیس vehicle را پیاده سازی می کند.
public class Car implements Vehicle {
    @Override
    public void cleanVehicle() {
        System.out.println("Cleaning the vehicle");
    }

    public static void main(String args[]){
        Car car = new Car();
        car.cleanVehicle();
        car.startVehicle();
    }
}
public interface Vehicle {

    void cleanVehicle();

    default void startVehicle() {
        System.out.println("Vehicle is starting");
    }
}
همانطور که در بالا نشان داده شده است ، کلاس ما فقط باید متد انتزاعی را پیاده سازی کند. هنگامی که ما متد پیش فرض را فراخوانی می کنیم ، کدی که در اینترفیس تعریف شده اجرا می شود.

نحوه حل مشکلات ایجاد شده به دلیل متدهای پیش فرض

اگرچه معرفی متدهای پیش فرض بروزرسانی بسیار خوبی برای جاوا بود و توسعه را بسیار آسان کرد ، اما آنها یک نکته احتیاطی دارند که باید هنگام کد نویسی مورد توجه قرار گیرد. برای دیدن این نکته ، به یک مثال نگاه می کنیم. در اینجا ، ما دو اینترفیس با یک متد پیش فرض همنام ، یعنی ()printSomething داریم.

اینترفیس InterfaceA:

public interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}

اینترفیس InterfaceB:

public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
حال ما یک کلاس Main تعریف خواهیم کرد که هر دو این اینترفیس ها را پیاده سازی کند. قبل از ادامه کار ، می خواهم در مورد سوالات زیر فکر کنید:
  1. آیا لازم است که متد ()printSomething را در کلاس Main پیاده سازی کنیم؟ اگر ما این کار را نکنیم آیا کلاس کامپایل می شود؟
  2. اگر شی از جنس کلاس Main داشته باشیم و متد ()printSomething را از این شی فراخوانی کنیم ، کدام پیاده سازی فراخوانی می شود؟ آیا متد تعریف شده در InterfaceA فراخوانی می شود یا متد تعریف شده در InterfaceB فراخوانی می شود؟
قبل از اینکه به این سوالات پاسخ دهم ، اجازه دهید کلاس Main را ایجاد کنیم که هر دو اینترفیس را پیاده سازی می کند.
public class Main implements InterfaceA, InterfaceB {

}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
کلاس فوق به دلیل مشکل Diamond در جاوا کامپایل نخواهد شد. برای حل مشکل کامپایل نشدن ، باید متد ()printSomething را به صورت زیر پیاده سازی کنیم:
public class Main implements InterfaceA, InterfaceB {

    @Override
    public void printSomething() {

        //Option 1 -> Provide our own implementation.
        System.out.println("I am inside Main class");

        //Option 2 -> Use existing implementation from interfaceA or interfaceB or both.
        InterfaceA.super.printSomething();
        InterfaceB.super.printSomething();
    }

    public static void main(String args[]){
         Main main = new Main();
         main.printSomething();
    }
}
public interface InterfaceB {

    default void printSomething() {
        System.out.println("I am inside B interface");
    }
}
interface InterfaceA {

    default void printSomething() {
        System.out.println("I am inside A interface");
    }
}
در این جلسه متدهای پیش فرض را معرفی کردیم و نحوه استفاده از آنها و کاربرد آنها را مشاهده کردید. در جلسه بعدی ، با متدهای استاتیک در اینترفیس ها آشنا خواهید شد.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا