JavaRush /وبلاگ جاوا /Random-FA /روش های پیش فرض در رابط ها

روش های پیش فرض در رابط ها

در گروه منتشر شد
هر نسخه جدید جاوا با نسخه های قبلی متفاوت است. در اینجا نمونه ای از تغییرات مربوط به مطالبی که پوشش دادیم آورده شده است: قبل از جاوا 5، هیچ enumعلامتی در زبان وجود نداشت.
روش های پیش فرض در رابط ها - 1
به همین ترتیب، جاوا 8 تفاوت قابل توجهی با جاوا 7 دارد. بیشتر سخنرانی های ما به نسخه هفتم این زبان نوشته شده است، اما، البته، نوآوری های مهم را نادیده نخواهیم گرفت. از آنجایی که در این سخنرانی در مورد رابط ها صحبت می کنیم، اجازه دهید به یک به روز رسانی نگاه کنیم - روش های پیش فرض در رابط ها . شما قبلاً می دانید که یک رابط پیاده سازی نمی شود . وظیفه آن این است که توصیف کند همه اشیایی که آن را پیاده سازی می کنند چه رفتاری باید داشته باشند . اما اغلب توسعه دهندگان با موقعیت هایی مواجه می شدند که پیاده سازی یک متد در همه کلاس ها یکسان بود. بیایید به نمونه ماشین قدیمی خود نگاه کنیم:
public interface Car {

   public void gas();

   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class Truck implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class F1Car implements Car {
   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}
به نظر شما مشکل اصلی این کد چیست؟ احتمالاً متوجه شده اید که ما یک سری کد مشابه را نوشتیم! این مشکل در برنامه نویسی رایج است و باید از آن اجتناب کرد. نکته دیگر این است که قبل از انتشار جاوا 8 گزینه های راه حل خاصی وجود نداشت. زمانی که این نسخه منتشر شد، امکان تعریف متدهای پیش فرض و پیاده سازی آن ها در داخل اینترفیس وجود داشت! در اینجا نحوه انجام آن آمده است:
public interface Car {

   public default void gas() {
       System.out.println("Газ!");
   }

   public default void brake() {
       System.out.println("Тормоз!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
حالا متدها gas()و brake(), که برای همه ماشین ها یکسان بود در اینترفیس گنجانده شده و نیازی به کد تکراری نیست. علاوه بر این، روش ها در هر یک از کلاس ها موجود است!
public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
اگر 100 کلاس با یک متد وجود داشته باشد gas()، اما فقط 99 تای آنها رفتار مشابهی داشته باشند، چه؟ این همه چیز را خراب می کند و روش پیش فرض در این مورد کار نمی کند؟ البته نه :) روش های پیش فرض رابط ها را می توان نادیده گرفت.
public class UnusualCar implements Car {
   @Override
   public void gas() {
       System.out.println("Эта машина газует по-другому!");
   }

   @Override
   public void brake() {
       System.out.println("Эта машина тормозит по-другому!");
   }
}
همه 99 نوع ماشین دیگر روش پیش فرض را اجرا می کنند و کلاس UnusualCar- استثنا - تصویر کلی را خراب نمی کند و با آرامش رفتار آن را تعیین می کند. وراثت چندگانه در رابط ها همانطور که می دانید، در جاوا وراثت چندگانه وجود ندارد. دلایل زیادی برای این امر وجود دارد که ما در یک سخنرانی جداگانه به آنها خواهیم پرداخت. در زبان های دیگر، برای مثال، در C++، برعکس است. بدون وراثت چندگانه، یک مشکل جدی ایجاد می شود: یک شیء می تواند تعدادی ویژگی و «رفتار» متفاوت داشته باشد. مثالی از زندگی: برای والدین خود ما بچه هستیم، برای معلمان دانش آموز، برای پزشکان بیمار هستیم. در زندگی، ما در نقش های مختلف ظاهر می شویم و بر این اساس، رفتار متفاوتی داریم: بدیهی است که با معلمان به گونه ای متفاوت از دوستان نزدیک صحبت خواهیم کرد. بیایید سعی کنیم این وضعیت را به کد ترجمه کنیم. بیایید تصور کنیم که ما دو کلاس داریم: Pond و Aviary. برای یک برکه به پرنده های شنا و برای یک پرنده پرنده به پرنده نیاز دارید. برای انجام این کار، دو کلاس پایه ایجاد کردیم - FlyingBirdو Waterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
بر این اساس، ما آن دسته از پرندگان را که طبقات آنها به ارث رسیده است FlyingBird، و آنها را به حوض می فرستیم - آنهایی را که از آنها فرود می آیند Waterfowl. همه چیز ساده به نظر می رسد. اما اگر بخواهیم اردک را در جایی شناسایی کنیم، چه کار خواهیم کرد؟ او هم شنا می کند و هم پرواز می کند. اما ما چندین وراثت نداریم. خوشبختانه جاوا پیاده سازی های متعددی از اینترفیس ها را ارائه می دهد. اگر یک کلاس نتواند از چندین والدین ارث ببرد، پیاده سازی چندین رابط آسان است! اردک ما هم می تواند پرواز کند و هم شنا :) کافی است FlyingBirdبه جای Waterfowlکلاس ها از رابط ها استفاده کنیم تا به نتیجه دلخواه برسیم.
public class Duck implements FlyingBird, Waterfowl {

   //методы обоих интерфейсов легко объединяются в одном классе

   @Override
   public void fly() {
       System.out.println("Летим!");
   }

   @Override
   public void swim() {

       System.out.println("Плывем!");
   }
}
به لطف این، برنامه ما مدیریت کلاس انعطاف پذیری را حفظ می کند و در ترکیب با اجرای روش های پیش فرض، توانایی ما برای تعریف رفتار اشیا تقریباً نامحدود می شود! :)
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION