JavaRush /Java Blogu /Random-AZ /Xüsusi nümunələrlə Java-da abstrakt siniflər

Xüsusi nümunələrlə Java-da abstrakt siniflər

Qrupda dərc edilmişdir
Salam! Əvvəlki mühazirələrdə biz interfeyslərlə tanış olduq və onların nə üçün lazım olduğunu anladıq. Bugünkü mövzunun əvvəlki ilə ortaq cəhətləri olacaq. Java-da abstrakt siniflərdən danışaq . Java-da konkret nümunələrlə abstrakt dərslər - 1

Niyə dərslər "abstrakt" adlanır

Yəqin ki, "abstraksiya" nın nə olduğunu xatırlayırsınız - biz artıq onu əhatə etmişik :) Birdən unutmusunuzsa, eybi yoxdur, xatırlayaq: bu OOP prinsipidir , ona görə sinifləri tərtib edərkən və obyektlər yaratarkən vurğulamaq lazımdır. obyektin yalnız əsas xassələrini və ikinci dərəcəli olanları atın. Məsələn, bir sinif - məktəb müəllimi layihələndiririksə SchoolTeacher, çətin ki, " hündürlük " xarakteristikasına ehtiyacımız var. Həqiqətən: müəllim üçün bu xüsusiyyət vacib deyil. Amma proqramda bir sinif BasketballPlayer- basketbolçu yaratsaq, boy əsas xüsusiyyətlərdən birinə çevriləcəkdir. Beləliklə, mücərrəd sinif gələcək siniflər qrupu üçün ən mücərrəd, o qədər də təxmini “boşdur”. Bu hazırlıq hazır formada istifadə edilə bilməz - çox "xamdır". Lakin o, gələcək siniflərin - mücərrəd sinfin varislərinin malik olacağı müəyyən ümumi vəziyyəti və davranışı təsvir edir.

Java Abstrakt Sinif Nümunələri

Avtomobillərlə bağlı sadə bir nümunəyə baxaq:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
Ən sadə abstrakt sinif belə görünür. Gördüyünüz kimi, xüsusi bir şey yoxdur :) Bu bizə nə üçün lazım ola bilər? Hər şeydən əvvəl o, bizə lazım olan varlığı ən mücərrəd şəkildə təsvir edir - avtomobil. Abstrakt sözünün burada bir səbəbi var. Dünyada “sadəcə maşınlar” yoxdur. Yük maşınları, yarış avtomobilləri, sedanlar, kupelər, yolsuzluq avtomobilləri var. Bizim mücərrəd sinifimiz sadəcə olaraq daha sonra avtomobil sinifləri yaradacağımız “plan”dır.
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}
Bu, miras haqqında mühazirələrdə danışdığımıza çox bənzəyir. CarYalnız orada mücərrəd olmayan bir sinif və onun metodları var idi . Lakin bu həllin bir sıra çatışmazlıqları var, onlar abstrakt dərslərdə düzəldilir. Hər şeydən əvvəl, mücərrəd sinif nümunəsi yaradıla bilməz:
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Bu “hiylə” xüsusi olaraq Java yaradıcıları tərəfindən həyata keçirilmişdir. Bir daha xatırlamaq lazımdır: mücərrəd sinif gələcək "normal" siniflər üçün sadəcə bir plandır . Rəsmin surətlərinə ehtiyacınız yoxdur, elə deyilmi? Beləliklə, abstrakt sinif nümunələri yaratmağa ehtiyac yoxdur :) Və əgər sinif Carmücərrəd olmasaydı, biz asanlıqla onun obyektlərini yarada bilərdik:
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
İndi proqramımızda bir növ anlaşılmaz avtomobil var - yük maşını deyil, yarış maşını deyil, sedan deyil, ümumiyyətlə bir şey var. Təbiətdə olmayan həmin “sadəcə maşın”. Eyni nümunəni heyvanlarla da göstərmək olar. Təsəvvür edin ki, proqramınızda obyektlər peyda olub Animal- “ sadəcə heyvan ”. Hansı növdür, hansı ailəyə aiddir, hansı xüsusiyyətlərə malik olduğu aydın deyil. Onu verilişdə görmək qəribə olardı. Təbiətdə "sadəcə heyvanlar" yoxdur. Yalnız itlər, pişiklər, tülkülər, mollar və başqaları. Abstrakt dərslər bizi “ sadəcə obyektlərdən ” azad edir. Bizə əsas vəziyyət və davranış verirlər. Məsələn, bütün avtomobillərin modeli , rəngimaksimal sürəti olmalıdır , onlar da qazəyləc tuta bilməlidirlər . Hamısı budur. Bu ümumi bir mücərrəd sxemdir, sonra sizə lazım olan dərsləri özünüz tərtib edirsiniz. Diqqət edin: mücərrəd sinifdə iki üsul da mücərrəd olaraq təyin olunur və onlar ümumiyyətlə həyata keçirilmir. Səbəb eynidir: mücərrəd siniflər "sadəcə maşınlar" üçün "defolt davranış" yaratmır. Sadəcə deyirlər ki, bütün maşınları hazırlaya bilsinlər. Bununla belə, əgər hələ də standart davranışa ehtiyacınız varsa, metodları abstrakt sinifdə tətbiq edə bilərsiniz. Java bunu qadağan etmir:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();

   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Konsol çıxışı: "Sürətləndirin!" Gördüyünüz kimi, biz abstrakt sinifdə bir metodu həyata keçirdik, ikincisini həyata keçirmədik. Nəticədə, sinifimizin davranışı Sedaniki hissəyə bölündü: onun üzərində metod çağırsanız gas(), o, ana abstrakt sinifdən “yuxarı çəkəcək” Carbrake()biz sinifdə metodu yenidən təyin etdik Sedan. Çox rahat və çevik olduğu ortaya çıxdı. Amma indi bizim sinif o qədər də abstrakt deyil ? Axı əslində onun metodlarının yarısı həyata keçirilir. Əslində - və bu çox vacib xüsusiyyətdir - bir sinif onun metodlarından ən azı biri mücərrəddirsə, mücərrəddir . Ən azı ikidən biri, min üsuldan ən azı biri - fərqi yoxdur. Biz hətta bütün üsulları həyata keçirə bilərik və heç bir mücərrəd olanları buraxmaya bilərik. Mücərrəd metodlar olmadan abstrakt sinif olacaq. Prinsipcə, bu mümkündür və tərtibçi səhvlər yaratmayacaq, lakin bunu etməmək daha yaxşıdır: abstrakt sözü mənasını itirəcək və proqramçı yoldaşlarınız bunu görəndə çox təəccüblənəcəklər :/ Üstəlik, bir metod abstrakt sözü ilə işarələnir, hər bir nəsil sinfi həyata keçirməli və ya abstrakt elan edilməlidir. Əks halda kompilyator xəta atacaq . Təbii ki, hər bir sinif yalnız bir abstrakt sinifdən miras ala bilər, ona görə də irsiyyət baxımından abstrakt və adi siniflər arasında heç bir fərq yoxdur. Mücərrəd sinifdən və ya adi sinifdən miras almağımızın fərqi yoxdur, yalnız bir ana sinif ola bilər.

Niyə Java-da çoxsaylı sinif miraslığı yoxdur?

Artıq Java-da çoxlu miras olmadığını söylədik, lakin bunun səbəbini başa düşmədik. İndi bunu cəhd edək. Məsələ burasındadır ki, əgər Java çoxlu irsiyyətə malik olsaydı, uşaq siniflər hansı davranışı seçəcəklərinə qərar verə bilməzdilər. Tutaq ki, iki sinifimiz var - TosterNuclearBomb:
public class Toster {


 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
Gördüyünüz kimi hər ikisinin də bir üsulu var on(). Toster vəziyyətində tost bişirməyə başlayır, nüvə bombası vəziyyətində isə partlayışa səbəb olur. Oh :/ İndi təsəvvür edin ki, aralarında bir şey yaratmağa qərar verdiniz (bilmirəm niyə birdən!). Və burada sizin sinifinizdir - MysteriousDevice! Bu kod, əlbəttə ki, işləmir və biz onu sadəcə olaraq “necə ola bilər” nümunəsi kimi təqdim edirik:
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
Görək nə əldə etdik. Sirli cihaz həm Tosterdən, həm də Nüvə Bombasından gəlir. Hər ikisinin metodu var on()və nəticədə obyekti çağırsaq hansı metodun on()atəşə tutulması lazım olduğu aydın deyil. MysteriousDeviceObyekt bunu başa düşə bilməyəcək. Yaxşı, tortda albalı kimi: Nüvə Bombasının heç bir üsulu yoxdur off(), buna görə də səhv təxmin etsək, cihazı söndürmək üçün heç bir yol olmayacaq. Java-da konkret nümunələrlə abstrakt dərslər - 2 Məhz bu çaşqınlıq üzündən, obyektin hansı davranışı seçməli olduğu aydın olmayanda, Java yaradıcıları çoxsaylı varislikdən imtina etdilər. Bununla belə, Java siniflərinin bir çox interfeys tətbiq etdiyini xatırlayırsınız. Yeri gəlmişkən, siz artıq təhsilinizdə ən azı bir abstrakt siniflə qarşılaşmısınız! Baxmayaraq ki, bəlkə də fərqinə varmadım :)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Bu sizin köhnə dostunuzdur Calendar. Mücərrəddir və bir neçə varis var. Onlardan biri GregorianCalendar. Siz artıq tarixlər haqqında dərslərdə istifadə etmişdiniz :) Hər şey aydın görünür, yalnız bir məqam qalıb: abstrakt siniflər və interfeyslər arasında əsas fərq nədir ? Niyə hər ikisini Java-ya əlavə etdilər və yalnız biri ilə məhdudlaşmadılar? Bu kifayət qədər ola bilər. Növbəti mühazirədə bu haqda danışacağıq! görüşənədək :)
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION