CodeGym/Java Blogu/Rastgele/Yuvalanmış sınıfların kalıtımı örnekleri
John Squirrels
Seviye
San Francisco

Yuvalanmış sınıfların kalıtımı örnekleri

grupta yayınlandı
MERHABA! Bugün önemli bir mekanizmaya bakacağız: iç içe sınıflarda kalıtım. İç içe geçmiş bir sınıfın başka bir sınıfı miras alması gerektiğinde ne yapacağınızı hiç düşündünüz mü? Değilse, inanın bana: bu durum kafa karıştırıcı olabilir çünkü pek çok nüans var.
  1. İç içe geçmiş bir sınıfın bir sınıfı miras almasını mı sağlıyoruz? Yoksa bazı sınıfların iç içe geçmiş bir sınıfı miras almasını mı sağlıyoruz?
  2. Çocuk/ebeveyn sınıfı sıradan bir genel sınıf mı, yoksa aynı zamanda iç içe geçmiş bir sınıf mı?
  3. Son olarak, tüm bu durumlarda ne tür iç içe geçmiş sınıflar kullanıyoruz?
Tüm bu soruların o kadar çok olası cevabı var ki, başınız dönecek :) Bildiğiniz gibi karmaşık bir problemi daha basit parçalara ayırarak çözebiliriz. Hadi bunu yapalım. Her bir iç içe geçmiş sınıf grubunu sırasıyla iki açıdan ele alalım: her bir iç içe sınıf türünü kimler miras alabilir ve kimler miras alabilir. Statik iç içe sınıflarla başlayalım.

Statik iç içe sınıflar

Yuvalanmış sınıfların kalıtım örnekleri - 2Kalıtım kuralları en basit olanıdır. Burada kalbinizin arzu ettiği hemen hemen her şeyi yapabilirsiniz. Statik iç içe geçmiş bir sınıf şunları miras alabilir:
  • sıradan bir sınıf
  • bir dış sınıfta veya atalarında bildirilen statik iç içe geçmiş bir sınıf
Statik iç içe sınıflarla ilgili dersimizden bir örneği hatırlayın.
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;
       }
   }
}
DrawingKodu değiştirmeye ve statik bir iç içe sınıf ve onun soyundan gelen — oluşturmaya çalışalım 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;
       }
   }
}
Gördüğünüz gibi sorun yok. Hatta sınıfı çıkarıp Drawingstatik iç içe geçmiş bir sınıf yerine sıradan bir genel sınıf haline getirebiliriz - hiçbir şey değişmeyecek.
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;
       }
   }
}
Bunu anlıyoruz. Ancak hangi sınıflar statik iç içe bir sınıfı miras alabilir? Pratik olarak herhangi! İç içe/yuvasız, statik/statik olmayan — fark etmez. Boeing737DrawingBurada , iç sınıfın statik iç içe sınıfı miras almasını sağlıyoruz 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;
       }
   }
}
Bunun gibi bir örnek oluşturabilirsiniz Boeing737Drawing:
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());

   }

}
Sınıfımız statik bir sınıfı miras almasına rağmen Boeing737Drawing, kendisi statik değildir! Sonuç olarak, her zaman dış sınıfın bir örneğine ihtiyaç duyacaktır. Boeing737DrawingSınıfı sınıftan çıkarabilir Boeing737ve basit bir genel sınıf haline getirebiliriz. Hiçbirşey değişmez. Hâlâ statik iç içe sınıfı devralabilir 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;

}
Tek önemli nokta, bu durumda statik değişkeni herkese açık hale getirmemiz gerektiğidir maxPassengersCount. Özel kalırsa, sıradan bir genel sınıf ona erişemez. Statik sınıfları bulduk! :) Şimdi iç sınıflara geçelim. 3 türde gelirler: basit iç sınıflar, yerel sınıflar ve anonim iç sınıflar. Yuvalanmış sınıfların kalıtım örnekleri - 3Yine basitten karmaşığa geçelim :)

Anonim iç sınıflar

Anonim bir iç sınıf, başka bir sınıfı miras alamaz. Başka hiçbir sınıf, anonim bir sınıfı miras alamaz. Daha basit olamazdı! :)

Yerel sınıflar

Yerel sınıflar (unuttuysanız) başka bir sınıfın kod bloğu içinde bildirilir. Çoğu zaman, bu, dış sınıfın bazı yöntemlerinde olur. Mantıksal olarak, yalnızca aynı yöntem (veya kod bloğu) içindeki diğer yerel sınıflar bir yerel sınıfı miras alabilir. İşte bir örnek:
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 {


       }

       // ...number validation code
   }
}
Bu, yerel sınıflar hakkındaki dersimizin kodudur. Sayı doğrulayıcı sınıfımızın PhoneNumberyerel bir sınıfı var. Örneğin, bir cep telefonu numarası ve bir sabit telefon numarası gibi iki farklı varlığı temsil etmesi gerekiyorsa, bunu yalnızca aynı yöntem içinde yapabiliriz. Nedeni basit: Yerel bir sınıfın kapsamı, bildirildiği yöntemle (kod bloğu) sınırlıdır. Sonuç olarak, onu harici olarak kullanamayacağız (sınıf kalıtımı dahil). Ancak, yerel sınıfın kendi içindeki kalıtım olasılıkları çok daha geniştir! Yerel bir sınıf şunları miras alabilir:
  1. Sıradan bir sınıf.
  2. Yerel sınıfla aynı sınıfta veya atalarından birinde bildirilen bir iç sınıf.
  3. Aynı yöntemde (kod bloğu) bildirilen başka bir yerel sınıf.
Birinci ve üçüncü noktalar bariz görünüyor, ancak ikincisi biraz kafa karıştırıcı :/ İki örneğe bakalım. Örnek 1 — "Yerel bir sınıfın, yerel sınıfla aynı sınıfta bildirilen bir iç sınıfı devralmasını sağlamak":
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);
           }
       }

       // ...number validation code
   }
}
PhoneNumberBurada sınıfı metottan çıkardık validatePhoneNumber()ve yerel bir sınıf yerine bir iç sınıf haline getirdik. Bu, 2 yerel sınıfımızın onu miras almasını engellemez. Örnek 2 — "... veya bu sınıfın atalarında." Şimdi bu zaten daha ilginç. PhoneNumberMiras zincirinde daha da yükseğe çıkabiliriz . AbstractPhoneNumberValidatorSınıfımızın atası olacak soyut bir sınıf ilan edelim 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;
       }
   }

}
Gördüğünüz gibi, sadece ilan etmedik, aynı zamanda PhoneNumberiç sınıfı da içine taşıdık. Ancak, soyundan gelen PhoneNumberValidatoryöntemlerde bildirilen yerel sınıflar, PhoneNumbersorunsuz bir şekilde miras alabilir!
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);
           }
       }

       // ...number validation code
   }
}
Kalıtım ilişkisi nedeniyle, bir alt sınıf içindeki yerel sınıflar, bir üst sınıf içindeki iç sınıfları "görür". Ve son olarak son gruba geçelim :)

İç sınıflar

Aynı dış sınıfta (veya onun alt sınıfında) bildirilen bir iç sınıf, başka bir iç sınıfı miras alabilir. Bunu, iç sınıflar dersindeki bisiklet örneğimizi kullanarak keşfedelim.
public class Bicycle {

   private String model;
   private int maxWeight;

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

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

   class Seat {

       public void up() {

           System.out.println("Seat up!");
       }

       public void down() {

           System.out.println("Seat down!");
       }
   }

   class SportSeat extends Seat {

       // ...methods
   }
}
SeatBurada sınıfın içindeki iç sınıfı ilan ettik Bicycle. Özel bir yarış koltuğu türü SportSeatonu devralır. Ancak, ayrı bir "yarış bisikleti" türü oluşturabilir ve onu ayrı bir sınıfa koyabiliriz:
public class SportBicycle extends Bicycle {

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


   class SportSeat extends Seat {

       public void up() {

           System.out.println("Seat up!");
       }

       public void down() {

           System.out.println("Seat down!");
       }
   }
}
Bu da bir seçenektir. Torunun iç sınıfı ( SportBicycle.SportSeat), ataların iç sınıflarını "görür" ve onları miras alabilir. İç sınıfları devralmanın çok önemli bir özelliği var! Önceki iki örnekte, sınıfımız SportSeatbir iç sınıftı. SportSeatAncak , aynı anda iç sınıfı miras alan sıradan bir genel sınıf yapmaya karar verirsek ne olur Seat?
// Error! No enclosing instance of type 'Bicycle' is in scope
class SportSeat extends Bicycle.Seat {

   public SportSeat() {

   }

   public void up() {

       System.out.println("Seat up!");
   }

   public void down() {

       System.out.println("Seat down!");
   }
}
Bir hatamız var! Nedenini tahmin edebilir misin? :) Her şey çok basit. İç sınıftan bahsettiğimizde Bicycle.Seat, dış sınıfın bir örneğine yapılan bir başvurunun dolaylı olarak iç sınıfın yapıcısına iletildiğinden bahsetmiştik. SeatBu, bir nesne yaratmadan bir nesne yaratamayacağınız anlamına gelir Bicycle. Peki ya a'nın yaratılması SportSeat? 'dan farklı olarak Seat, oluşturucuya dış sınıfın bir örneğine bir referansı dolaylı olarak iletmek için bu yerleşik mekanizmaya sahip değildir. Şimdiye kadar, bir nesne olmadan , tıpkı durumunda olduğu gibi, Bicyclebir nesne yaratamayız . Bu nedenle, yapmamız gereken tek bir şey kaldı - yapıcıya açıkça bir nesne referansı iletmek . Bunu nasıl yapacağınız aşağıda açıklanmıştır: SportSeatSeatSportSeatBicycle
class SportSeat extends Bicycle.Seat {

   public SportSeat(Bicycle bicycle) {

       bicycle.super();
   }

   public void up() {

       System.out.println("Seat up!");
   }

   public void down() {

       System.out.println("Seat down!");
   }
}
Now kullanarak üst sınıf yapıcısını çağırıyoruz super(); , eğer bir nesne yaratmak istiyorsak SportSeat, hiçbir şey bizi bunu yapmaktan alıkoyamaz:
public class Main {

   public static void main(String[] args) {

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

   }
}
Vay! Bu ders oldukça uzundu :) Ama çok şey öğrendiniz! Şimdi bazı görevleri çözme zamanı! :)
Yorumlar
  • Popüler
  • Yeni
  • Eskimiş
Yorum bırakmak için giriş yapmalısınız
Bu sayfada henüz yorum yok