JavaRush /Blog Jawa /Random-JV /Warisan kelas nested

Warisan kelas nested

Diterbitake ing grup
Hello! Dina iki kita bakal katon ing operasi saka mekanisme penting - warisan ing kelas nested. Aku ora ngerti yen sampeyan wis tau mikir bab apa sing bakal nindakake nalika sampeyan kudu oleh warisan kelas nested saka sawetara liyane. Yen ora, percaya marang aku: kahanan iki bisa mbingungake, amarga ana akeh nuansa ing kene:
  1. Apa kita marisi kelas nested saka sawetara kelas utawa kita marisi kelas liyane saka kelas nested?
  2. Apa penerus / marisi kelas umum biasa, utawa uga kelas nested?
  3. Pungkasan, apa jinis kelas nested sing digunakake ing kabeh kahanan kasebut?
Yen sampeyan mangsuli kabeh pitakonan kasebut, bakal ana akeh jawaban sing bisa dadi sirahmu :) Kaya sing sampeyan ngerti, kanggo ngatasi masalah sing rumit, sampeyan kudu dibagi dadi bagean sing luwih gampang. Sing bakal kita tindakake. Ayo katon ing saben klompok kelas nested ing siji saka rong perspektif: sing bisa oleh warisan saka jinis iki nested kelas, lan saka sapa bisa oleh warisan. Ayo dadi miwiti karo kelas nested statis.

Kelas nested statis

Conto warisan kelas internal - 2Aturan warisan sing paling gampang. Ing kene sampeyan bisa nindakake meh kabeh sing dikarepake. Kelas nested statis bisa diwarisake saka:
  • kelas biasa
  • kelas nested statis sing diumumake ing kelas njaba utawa leluhure
Ayo elinga conto saka kuliah babagan kelas bersarang statis.
public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

       public static int getMaxPassengersCount() {

           return maxPassengersCount;
       }
   }
}
Ayo nyoba ngganti kode lan nggawe kelas nested statis Drawinglan turunane - Boeing737Drawing.
public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

   }

   public static class Boeing737Drawing extends Drawing {

       public static int getMaxPassengersCount() {

           return maxPassengersCount;
       }
   }
}
Nalika sampeyan bisa ndeleng, ora masalah. Kita bisa mbusak kabeh kelas Drawinglan nggawe kelas umum biasa tinimbang nested statis - ora ana sing bakal diganti.
public class Drawing {

}

public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Boeing737Drawing extends Drawing {

       public static int getMaxPassengersCount() {

           return maxPassengersCount;
       }
   }
}
Sing diurutake. Lan kelas apa sing bisa diwarisake saka nested statis? Meh wae! Nested/regular, statis/non-statis - ora masalah. Ing kene kita warisake kelas batin Boeing737Drawingsaka sarang statis Drawing:
public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

   }

   public class Boeing737Drawing extends Drawing {

       public int getMaxPassengersCount() {

           return maxPassengersCount;
       }
   }
}
Sampeyan bisa nggawe conto Boeing737Drawingkaya iki:
public class Main {

   public static void main(String[] args) {

      Boeing737 boeing737 = new Boeing737(1990);
      Boeing737.Boeing737Drawing drawing = boeing737.new Boeing737Drawing();
      System.out.println(drawing.getMaxPassengersCount());

   }

}
Senajan kelas kita Boeing737Drawingwarisan saka kelas statis, iku dhewe ora statis! Mulane bakal tansah mbutuhake conto saka kelas njaba. Kita bisa njupuk kelas Boeing737Drawingmetu saka kelas Boeing737lan nggawe mung kelas umum. Ora ana sing bakal diganti - uga bisa warisan saka nested statis Drawing.
public class Boeing737 {

   private int manufactureYear;
   public static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

   }
}

public class Boeing737Drawing extends Boeing737.Drawing {

   public int getMaxPassengersCount() {

       return Boeing737.maxPassengersCount;

}
Siji-sijine titik penting: ing kasus iki, kita kudu nggawe maxPassengersCountpublik variabel statis. Yen tetep pribadi, kelas umum normal ora bakal bisa ngakses. Kita wis ngurutake kelas statis! :) Saiki ayo pindhah menyang kelas batin. Nalika sampeyan ngelingi, ana 3 jinis: kelas njero, kelas lokal lan kelas njero anonim. Conto warisan kelas internal - 3Maneh, ayo pindhah saka prasaja menyang kompleks :)

Kelas batin anonim

Kelas batin anonim ora bisa oleh warisan saka kelas liya. Ora ana kelas liyane sing bisa entuk warisan saka kelas anonim. Iku ora bisa dadi luwih prasaja! :)

Kelas lokal

Kelas lokal (yen sampeyan kelalen) diumumake ing blok kode kelas liyane. Paling asring - ing sawetara cara saka kelas njaba iki. Logis yen mung kelas lokal liyane ing metode (utawa blok) sing padha bisa entuk warisan saka kelas lokal. Iki contone:
public class PhoneNumberValidator {

   public void validatePhoneNumber(final String number) {

       class PhoneNumber {

           private String phoneNumber;

           public PhoneNumber() {
               this.phoneNumber = number;
           }

           public String getPhoneNumber() {
               return phoneNumber;
           }

           public void setPhoneNumber(String phoneNumber) {
               this.phoneNumber = phoneNumber;
           }
       }

       class CellPhoneNumber extends PhoneNumber {

       }

       class LandlinePhoneNumber extends PhoneNumber {


       }

       //...code валидации номера
   }
}
Iki kode saka kuliah kita babagan kelas lokal. Ing kelas validator nomer kita duwe kelas lokal PhoneNumber- nomer telpon. Yen kanggo tujuan kita kudu ngekstrak rong entitas sing kapisah, contone, nomer ponsel lan nomer telpon darat, kita mung bisa nindakake iki kanthi cara sing padha. Alesané prasaja: ruang lingkup kelas lokal ana ing cara (blok) sing diumumake. Mulane, kita ora bakal bisa nggunakake eksternal (kalebu kanggo warisan). Nanging, kelas lokal dhewe duwe kemungkinan luwih akeh kanggo warisan! Kelas lokal bisa warisan saka:
  1. Kelas biasa.
  2. Kelas batin sing diumumake ing kelas sing padha karo kelas lokal utawa ing leluhure.
  3. Saka kelas lokal liyane diumumake kanthi cara sing padha (blok).
Titik pisanan lan katelu katon jelas, nanging sing kapindho rada mbingungake: / Ayo ndeleng rong conto. Conto 1 - "warisan kelas lokal saka kelas batin sing diumumake ing kelas sing padha karo kelas lokal":
public class PhoneNumberValidator {

   class PhoneNumber {

       private String phoneNumber;

       public PhoneNumber(String phoneNumber) {
           this.phoneNumber = phoneNumber;
       }

       public String getPhoneNumber() {
           return phoneNumber;
       }

       public void setPhoneNumber(String phoneNumber) {
           this.phoneNumber = phoneNumber;
       }
   }

   public void validatePhoneNumber(final String number) {

       class CellPhoneNumber extends PhoneNumber {

           public CellPhoneNumber(String phoneNumber) {
               super(number);
           }
       }

       class LandlinePhoneNumber extends PhoneNumber {

           public LandlinePhoneNumber(String phoneNumber) {
               super(number);
           }
       }

       //...code валидации номера
   }
}
Kene kita wis njupuk kelas PhoneNumbermetu saka cara validatePhoneNumber()lan digawe iku internal tinimbang lokal. Iki ora nyegah kita saka warisan 2 kelas lokal saka iku. Conto 2 - "... utawa ing leluhur kelas iki." Iki ngendi iku dadi luwih menarik. Kita bisa njupuk PhoneNumbermalah luwih munggah chain saka warisan. Ayo ngumumake kelas abstrak AbstractPhoneNumberValidatorsing bakal dadi leluhur kita PhoneNumberValidator:
public abstract class AbstractPhoneNumberValidator {

   class PhoneNumber {

       private String phoneNumber;

       public PhoneNumber(String phoneNumber) {
           this.phoneNumber = phoneNumber;
       }

       public String getPhoneNumber() {
           return phoneNumber;
       }

       public void setPhoneNumber(String phoneNumber) {
           this.phoneNumber = phoneNumber;
       }
   }

}
Kaya sing sampeyan ngerteni, kita ora mung ngumumake, nanging uga mindhah kelas njero PhoneNumber. Nanging, ing kelas turunane - PhoneNumberValidator- kelas lokal ing metode bisa warisan saka PhoneNumber!
public class PhoneNumberValidator extends AbstractPhoneNumberValidator {

   public void validatePhoneNumber(final String number) {

       class CellPhoneNumber extends PhoneNumber {

           public CellPhoneNumber(String phoneNumber) {
               super(number);
           }
       }

       class LandlinePhoneNumber extends PhoneNumber {

           public LandlinePhoneNumber(String phoneNumber) {
               super(number);
           }
       }

       //...code валидации номера
   }
}
Thanks kanggo sambungan liwat warisan, kelas lokal ing kelas turunan "ndeleng" kelas batin ing leluhur. Lan pungkasane, ayo pindhah menyang grup pungkasan :)

Kelas batin

Kelas batin bisa diwarisake dening kelas batin liyane sing diumumake ing kelas njaba sing padha (utawa turunane). Ayo ndeleng iki nggunakake conto sepeda saka kuliah ing kelas batin.
public class Bicycle {

   private String model;
   private int mawWeight;

   public Bicycle(String model, int mawWeight) {
       this.model = model;
       this.mawWeight = mawWeight;
   }

   public void start() {
       System.out.println("Go!");
   }

   class Seat {

       public void up() {

           System.out.println("Сидение поднято выше!");
       }

       public void down() {

           System.out.println("Сидение опущено ниже!");
       }
   }

   class SportSeat extends Seat {

       //...methods
   }
}
BicycleIng kene kita ngumumake kelas internal ing njero kelas Seat- kursi. A subtipe khusus saka kursi racing dipun warisaken saka iku - SportSeat. Nanging, kita bisa nggawe jinis "sepeda balap" sing kapisah lan dilebokake ing kelas sing kapisah:
public class SportBicycle extends Bicycle {

   public SportBicycle(String model, int mawWeight) {
       super(model, mawWeight);
   }


   class SportSeat extends Seat {

       public void up() {

           System.out.println("Сидение поднято выше!");
       }

       public void down() {

           System.out.println("Сидение опущено ниже!");
       }
   }
}
Iki uga bisa. Kelas batine bocah ( SportBicycle.SportSeat) “ndeleng” kelas batine leluhur lan bisa oleh warisan. Warisan saka kelas batin nduweni fitur sing penting banget! Ing rong conto sadurunge kita SportSeatduwe internal. Nanging apa yen kita mutusake kanggo nggawe SportSeatkelas umum biasa, sing uga warisan saka kelas batin Seat?
//ошибка! No inclosing instance of  type 'Bicycle' is in scope
class SportSeat extends Bicycle.Seat {

   public SportSeat() {

   }

   public void up() {

       System.out.println("Сидение поднято выше!");
   }

   public void down() {

       System.out.println("Сидение опущено ниже!");
   }
}
Kita entuk kesalahan! Apa sampeyan bisa ngira apa hubungane? :) Iku prasaja. Nalika kita ngomong bab kelas njero Bicycle.Seat, kita kasebut sing konstruktor saka kelas utama implicitly liwat referensi kanggo obyek saka kelas njaba. Mulane, tanpa nggawe obyek, Bicyclesampeyan ora bisa nggawe obyek Seat. Kepiye babagan kreasi SportSeat? Iku ora padha dibangun ing mekanisme kanggo implicitly maringaken referensi kanggo obyek kelas njaba ing konstruktor minangka ing Seat. Nanging, tanpa obyek Bicycle, kaya ing kasus karo Seat, kita ora bisa nggawe obyek SportSeat. Mulane, kita duwe mung siji bab ngiwa - eksplisit pass SportSeatreferensi kanggo obyek kanggo konstruktor. BicycleMangkene carane ditindakake:
class SportSeat extends Bicycle.Seat {

   public SportSeat(Bicycle bicycle) {

       bicycle.super();
   }

   public void up() {

       System.out.println("Сидение поднято выше!");
   }

   public void down() {

       System.out.println("Сидение опущено ниже!");
   }
}
Kanggo iki, kita nggunakake tembung khusus super(); Saiki, yen kita pengin nggawe obyek SportSeat, ora ana sing bakal nyegah kita nindakake iki:
public class Main {

   public static void main(String[] args) {

       Bicycle bicycle = new Bicycle("Peugeot", 120);
       SportSeat peugeotSportSeat = new SportSeat(bicycle);

   }
}
Phew, kuliah ternyata cukup gedhe :) Nanging sampeyan sinau akeh perkara anyar! Saiki iki wektu kanggo ngatasi sawetara masalah! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION