CodeGym/Java Blogu/Rastgele/İç içe iç sınıflar
John Squirrels
Seviye
San Francisco

İç içe iç sınıflar

grupta yayınlandı
MERHABA! Bugün önemli bir konuyu ele alacağız - Java'da yuvalanmış sınıfların nasıl çalıştığı. Java, başka bir sınıfın içinde sınıflar oluşturmanıza izin verir:
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
Bu dahili sınıflara iç içe denir. 2 tipe ayrılırlar:
  1. Statik olmayan iç içe sınıflar. Bunlara iç sınıflar da denir.
  2. Statik iç içe sınıflar.
Buna karşılık, iç sınıfların iki farklı alt kategorisi vardır. Yalnızca bir iç sınıf olan bir iç sınıfa ek olarak, şu şekilde de olabilir:
  • yerel bir sınıf
  • isimsiz bir sınıf
Kafası karışmış? :) Sorun yok. İşte netlik için bir diyagram. Aniden kafanız karışırsa, ders sırasında ona geri dönün! İç içe iç sınıflar - 2Bugünün dersinde, iç sınıfları (statik olmayan yuvalanmış sınıflar olarak da bilinir) tartışacağız. Kaybolmamanız için genel şemada özel olarak vurgulanmıştır :) Bariz soruyla başlayalım: neden "iç" sınıflar olarak adlandırılıyorlar? Cevap oldukça basit: çünkü diğer sınıfların içinde yaratılıyorlar. İşte bir örnek:
public class Bicycle {

   private String model;
   private int weight;

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

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

   public class Handlebar {

       public void right() {
           System.out.println("Steer right!");
       }

       public void left() {

           System.out.println("Steer left!");
       }
   }

   public class Seat {

       public void up() {

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

       public void down() {

           System.out.println("Seat down!");
       }
   }
}
İşte sınıfımız var Bicycle. 2 alanı ve 1 yöntemi vardır: start(). İç içe iç sınıflar - 3İki sınıf içermesi bakımından sıradan bir sınıftan farklıdır: Handlebarve Seat. Kodları sınıfın içinde yazılır Bicycle. Bunlar tam teşekküllü sınıflardır: görebileceğiniz gibi, her birinin kendi yöntemleri vardır. Bu noktada, bir sorunuz olabilir: neden bir sınıfı diğerinin içine koyalım? Neden onları iç sınıflar yapalım? Peki, programımızda gidon ve koltuk kavramları için ayrı sınıflara ihtiyacımız olduğunu varsayalım. Bunları iç içe yapmamıza gerek yok elbette! Sıradan sınıflar yapabiliriz. Örneğin, bunun gibi:
public class Handlebar {
   public void right() {
       System.out.println("Steer right!");
   }

   public void left() {

       System.out.println("Steer left");
   }
}

public class Seat {

   public void up() {

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

   public void down() {

       System.out.println("Seat down!");
   }
}
Çok iyi soru! Elbette teknoloji ile sınırlı değiliz. Bunu yapmak kesinlikle bir seçenektir. Burada önemli olan, derslerin belirli bir program ve amacı açısından doğru tasarlanmasıdır. İç sınıflar, başka bir varlığa ayrılmaz bir şekilde bağlı olan bir varlığı ayırmak içindir. Gidon, koltuklar ve pedallar bir bisikletin bileşenleridir. Bisikletten ayrı, pek bir anlam ifade etmiyorlar. Tüm bu kavramları ayrı ortak sınıflar yapsaydık, programımızda şöyle bir kod olurdu:
public class Main {

   public static void main(String[] args) {
       Handlebar handlebar = new Handlebar();
       handlebar.right();
   }
}
Hmm... Bu kodun anlamını açıklamak bile zor. Biraz belirsiz gidonumuz var (Neden gerekli? Dürüst olmak gerekirse hiçbir fikrim yok). Ve bu kol sağa dönüyor... kendi kendine, bisikletsiz... nedense. Gidon kavramını bisiklet kavramından ayırarak programımızda biraz mantık kaybettik. Bir iç sınıf kullanıldığında kod çok farklı görünür:
public class Main {

   public static void main(String[] args) {

       Bicycle peugeot = new Bicycle("Peugeot", 120);
       Bicycle.Handlebar handlebar = peugeot.new Handlebar();
       Bicycle.Seat seat = peugeot.new Seat();

       seat.up();
       peugeot.start();
       handlebar.left();
       handlebar.right();
   }
}
Konsol çıktısı:
Seat up!
Let's go!
Steer left!
Steer right!
Şimdi gördüklerimiz aniden mantıklı geliyor! :) Bir bisiklet nesnesi oluşturduk. İki bisiklet "alt nesnesi" oluşturduk — bir gidon ve bir sele. Koltuğu konfor için yükselttik ve yola çıktık: gerektiği gibi pedal çevirin ve direksiyonu çevirin! :) İhtiyacımız olan yöntemler uygun nesneler üzerinde çağrılır. Hepsi basit ve kullanışlı. Bu örnekte gidonu ve seleyi ayırmak kapsüllemeyi geliştiriyor (bisiklet parçalarıyla ilgili verileri ilgili sınıf içinde saklıyoruz) ve daha detaylı bir soyutlama oluşturmamızı sağlıyor. Şimdi farklı bir duruma bakalım. Bir bisikletçiyi ve bisiklet yedek parçalarını simüle eden bir program oluşturmak istediğimizi varsayalım. İç içe iç sınıflar - 4Bu durumda, önceki çözümümüz işe yaramaz. Bir bisiklet mağazasında, her bir bisiklet parçası, bir bisikletten ayrılsa bile anlamlıdır. Örneğin, "bir müşteriye pedal satmak", "yeni bir koltuk satın almak" gibi yöntemlere ihtiyacımız olacak. kendine ait: bisiklet konseptinden ayrılabilir. İç sınıfları mı kullanayım yoksa tüm varlıkları ayrı sınıflar olarak mı düzenleyeyim diye merak ediyorsanız, tam da buna dikkat etmeniz gerekiyor. Nesne yönelimli programlama, gerçek dünya varlıklarını modellemeyi kolaylaştırması bakımından iyidir. İç sınıfları kullanıp kullanmayacağınıza karar verirken yol gösterici ilkeniz bu olabilir. Gerçek bir mağazada, yedek parçalar bisikletlerden ayrıdır - sorun değil. Bu, bir program tasarlarken de sorun olmadığı anlamına gelir. Tamam, "felsefeyi" bulduk :) Şimdi iç sınıfların önemli "teknik" özelliklerini tanıyalım. İşte kesinlikle hatırlamanız ve anlamanız gerekenler:
  1. Bir iç sınıfın nesnesi, bir dış sınıfın nesnesi olmadan var olamaz.

    SeatBu mantıklı: bu nedenle programımızda ve iç sınıfları oluşturduk Handlebar— böylece artık gidon ve koltuklarla yetinmeyiz.

    Bu kod derlenmiyor:

    public static void main(String[] args) {
    
       Handlebar handlebar = new Handlebar();
    }

    Bir diğer önemli özellik bundan kaynaklanmaktadır:

  2. Bir iç sınıfın nesnesi, dış sınıfın değişkenlerine erişebilir.

    int seatPostDiameterÖrneğin sınıfımıza (koltuk direğinin çapını temsil eden) bir değişken ekleyelim Bicycle.

    Ardından , iç sınıfta koltuk özelliklerini görüntüleyen Seatbir yöntem oluşturabiliriz :displaySeatProperties()

    public class Bicycle {
    
       private String model;
       private int weight;
    
       private int seatPostDiameter;
    
       public Bicycle(String model, int weight, int seatPostDiameter) {
           this.model = model;
           this.weight = weight;
           this.seatPostDiameter = seatPostDiameter;
    
       }
    
       public void start() {
           System.out.println("Let's go!");
       }
    
       public class Seat {
    
           public void up() {
    
               System.out.println("Seat up!");
           }
    
           public void down() {
    
               System.out.println("Seat down!");
           }
    
           public void displaySeatProperties() {
    
               System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter);
           }
       }
    }

    Ve şimdi bu bilgiyi programımızda görüntüleyebiliriz:

    public class Main {
    
       public static void main(String[] args) {
    
           Bicycle bicycle = new Bicycle("Peugeot", 120, 40);
           Bicycle.Seat seat = bicycle.new Seat();
    
           seat.displaySeatProperties();
       }
    }

    Konsol çıktısı:

    Seat properties: seatpost diameter = 40

    Not:yeni değişken, en katı erişim değiştiricisiyle ( ) bildirilir private. Ve yine de iç sınıfın erişimi var!

  3. Bir iç sınıfın nesnesi, bir dış sınıfın statik yönteminde yaratılamaz.

    Bu, iç sınıfların nasıl düzenlendiğine ilişkin belirli özelliklerle açıklanır. Bir iç sınıf, parametrelere sahip kuruculara veya yalnızca varsayılan kurucuya sahip olabilir. Ancak ne olursa olsun, bir iç sınıfın nesnesini oluşturduğumuzda, dış sınıfın nesnesine yapılan bir başvuru, iç sınıfın yaratılan nesnesine görünmez bir şekilde iletilir. Sonuçta, böyle bir nesne referansının varlığı mutlak bir gerekliliktir. Aksi takdirde, iç sınıfın nesnelerini oluşturamayız.

    Ancak, dış sınıfın bir yöntemi statik ise, o zaman dış sınıfın bir nesnesine sahip olmayabiliriz! Ve bu, bir iç sınıfın nasıl çalıştığına dair mantığın ihlali olur. Bu durumda derleyici bir hata üretecektir:

    public static Seat createSeat() {
    
       // Bicycle.this cannot be referenced from a static context
       return new Seat();
    }
  4. Bir iç sınıf, statik değişkenler ve yöntemler içeremez.

    Mantık aynıdır: statik yöntemler ve değişkenler var olabilir ve bir nesnenin yokluğunda bile çağrılabilir veya bunlara başvurulabilir.

    Ancak dış sınıftan bir nesne olmadan iç sınıfa erişimimiz olmaz.

    Açık bir çelişki! Bu nedenle iç sınıflarda statik değişkenlere ve yöntemlere izin verilmez.

    Bunları oluşturmaya çalışırsanız derleyici bir hata üretecektir:

    public class Bicycle {
    
       private int weight;
    
    
       public class Seat {
    
           // An inner class cannot have static declarations
           public static void displaySeatProperties() {
    
               System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter);
           }
       }
    }
  5. Bir iç sınıfın nesnesini oluştururken erişim değiştiricisi önemlidir.

    Bir iç sınıf, standart erişim değiştiricileri ile işaretlenebilir: public, private, protectedve package private.

    Bu neden önemli?

    Bu, programımızda iç sınıfın örneklerini nerede oluşturabileceğimizi etkiler.

    Sınıfımız Seatolarak bildirilirse , başka herhangi bir sınıfta nesneler publicoluşturabiliriz . SeatTek gereksinim, dış sınıftan bir nesnenin de var olması gerektiğidir.

    Bu arada, bunu zaten burada yaptık:

    public class Main {
    
       public static void main(String[] args) {
    
           Bicycle peugeot = new Bicycle("Peugeot", 120);
           Bicycle.Handlebar handlebar = peugeot.new Handlebar();
           Bicycle.Seat seat = peugeot.new Seat();
    
           seat.up();
           peugeot.start();
           handlebar.left();
           handlebar.right();
       }
    }

    HandlebarSınıftan iç sınıfa kolayca erişim sağladık Main.

    İç sınıfı olarak bildirirsek private, sadece dış sınıf içinde nesneler oluşturabileceğiz.

    SeatArtık "dışarıdan" bir nesne oluşturamayız :

    private class Seat {
    
       // Methods
    }
    
    public class Main {
    
       public static void main(String[] args) {
    
           Bicycle bicycle = new Bicycle("Peugeot", 120, 40);
    
           // Bicycle.Seat has private access in Bicycle
           Bicycle.Seat seat = bicycle.new Seat();
       }
    }

    Muhtemelen mantığı zaten anlamışsınızdır :)

  6. İç sınıflar için erişim değiştiricileri, sıradan değişkenlerle aynı şekilde çalışır.

    Değiştirici protected, aynı paketteki alt sınıflardaki ve sınıflardaki bir örnek değişkene erişim sağlar.

    protectedayrıca iç sınıflar için de çalışır. protectedİç sınıfın nesnelerini oluşturabiliriz :

    • dış sınıfta;
    • alt sınıflarında;
    • aynı paketteki sınıflarda.

    İç sınıfın bir erişim değiştiricisi ( ) yoksa package private, iç sınıfın nesneleri oluşturulabilir:

    • dış sınıfta;
    • aynı paketteki sınıflarda.

    Değiştiricilere uzun süredir aşinasınız, bu yüzden burada sorun yok.

Şimdilik bu kadar :) Ama gevşemeyin! İç sınıflar, bir sonraki derste keşfetmeye devam edeceğimiz oldukça kapsamlı bir konudur. Artık kursumuzun dahili sınıflar dersiyle ilgili hafızanızı tazeleyebilirsiniz . Ve bir dahaki sefere statik iç içe sınıflardan bahsedelim.
Yorumlar
  • Popüler
  • Yeni
  • Eskimiş
Yorum bırakmak için giriş yapmalısınız
Bu sayfada henüz yorum yok