CodeGym/Java Blogu/Rastgele/Yerel bir yöntemde iç sınıflar
John Squirrels
Seviye
San Francisco

Yerel bir yöntemde iç sınıflar

grupta yayınlandı
MERHABA! Başka bir iç içe sınıf türünden bahsedelim. Yerel sınıflardan bahsediyorum (yöntem-yerel iç sınıflar). Dalışa geçmeden önce iç içe sınıfların yapısındaki yerlerini hatırlamalıyız. Diyagramımızdan, yerel sınıfların, önceki materyallerdeYerel bir yöntemde iç sınıflar - 2 ayrıntılı olarak bahsettiğimiz iç sınıfların bir alt türü olduğunu görebiliriz . Bununla birlikte, yerel sınıfların bir takım önemli özellikleri ve sıradan iç sınıflardan farklılıkları vardır. Ana şey, bildirimlerinde: Yerel bir sınıf yalnızca bir kod bloğunda bildirilir. Çoğu zaman, bu bildirim, dış sınıfın bazı yöntemlerinin içindedir. Örneğin, şöyle görünebilir:
public class PhoneNumberValidator {

   public void validatePhoneNumber(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;
           }
       }

       // ...number validation code
   }
}
ÖNEMLİ!Java 7 kuruluysa, bu kod IDEA'ya yapıştırıldığında derlenmeyecektir. Bunun nedenlerini dersin sonunda konuşacağız. Kısacası, yerel sınıfların nasıl çalıştığı büyük ölçüde dilin sürümüne bağlıdır. Bu kod sizin için derlemezse, IDEA'daki dil sürümünü Java 8'e çevirebilir veya kelimeyi finalşu şekilde görünecek şekilde method parametresine ekleyebilirsiniz: validatePhoneNumber(final String number). Bundan sonra her şey işe yarayacak. Bu, telefon numaralarını doğrulayan küçük bir programdır. Yöntemi validatePhoneNumber()girdi olarak bir dize alır ve bunun bir telefon numarası olup olmadığını belirler. Ve bu metot içerisinde yerel sınıfımızı ilan ettik PhoneNumber. Nedenini makul bir şekilde sorabilirsiniz. Neden tam olarak bir yöntemin içinde bir sınıf bildiririz? Neden sıradan bir iç sınıf kullanmıyorsunuz? Doğru, yapabilirdikPhoneNumbersınıf bir iç sınıf. Ancak nihai çözüm, programınızın yapısına ve amacına bağlıdır. İç sınıflarla ilgili bir dersten örneğimizi hatırlayalım:
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!");
   }

   public class HandleBar {

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

       public void left() {

           System.out.println("Steer left!");
       }
   }
}
HandleBarİçinde, bisikletin bir iç sınıfını yaptık . Fark ne? Her şeyden önce, sınıfın kullanım şekli farklıdır. HandleBarİkinci örnekteki sınıf, birinci örnekteki sınıftan daha karmaşık bir varlıktır PhoneNumber. İlk olarak, HandleBarpublic rightve leftmetotları vardır (bunlar ayarlayıcılar/alıcılar değildir). İkincisi, ona ve dış sınıfına nerede ihtiyaç duyabileceğimizi önceden tahmin etmek imkansızdır Bicycle. Tek bir programda bile onlarca farklı yer ve yöntem olabilir. Ancak sınıfla PhoneNumberher şey çok daha basit. Programımız çok basit. Tek bir amacı vardır: bir numaranın geçerli bir telefon numarası olup olmadığını kontrol etmek. Çoğu durumda, bizimPhoneNumberValidatorbağımsız bir program bile olmayacak, daha çok daha büyük bir program için yetkilendirme mantığının bir parçası olacak. Örneğin, çeşitli web siteleri, kullanıcılar kaydolurken genellikle bir telefon numarası ister. Sayılar yerine saçma sapan bir şey girerseniz, web sitesi bir hata bildirir: "Bu bir telefon numarası değil!" Böyle bir web sitesinin (veya daha doğrusu kullanıcı yetkilendirme mekanizmasının) geliştiricileri, bizimkine benzer bir şey içerebilir.PhoneNumberValidatoronların kodunda. Başka bir deyişle, programda tek bir yerde kullanılacak ve başka hiçbir yerde kullanılacak tek yöntemli bir dış sınıfımız var. Ve eğer kullanılırsa, onda hiçbir şey değişmeyecektir: bir yöntem işini yapar ve o kadar. Bu durumda, tüm mantık tek bir yöntemde toplandığı için, orada ek bir sınıf kapsüllemek çok daha uygun ve uygun olacaktır. Bir alıcı ve ayarlayıcı dışında kendine ait bir yöntemi yoktur. Aslında, yalnızca yapıcıdan gelen verilere ihtiyacımız var. Diğer yöntemlerde yer almaz. Buna göre, kullanıldığı tek yöntem dışında onun hakkında bilgi almak için hiçbir sebep yoktur. Ayrıca, yerel bir sınıfın bir yöntemde bildirildiği bir örnek verdik, ancak bu tek seçenek değil. Basitçe bir kod bloğunda bildirilebilir:
public class PhoneNumberValidator {

   {
       class PhoneNumber {

           private String phoneNumber;

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

   }

   public void validatePhoneNumber(String phoneNumber) {


       // ...number validation code
   }
}
Hatta döngüde for!
public class PhoneNumberValidator {


   public void validatePhoneNumber(String phoneNumber) {

       for (int i = 0; i < 10; i++) {

           class PhoneNumber {

               private String phoneNumber;

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

           // ...some logic
       }

       // ...number validation code
   }
}
Ancak bu tür durumlar son derece nadirdir. Çoğu durumda, bildirim yöntemin içinde gerçekleşir. Böylece bildirimleri çözdük ve "felsefe" hakkında da konuştuk :) Yerel sınıfların iç sınıflara kıyasla ne gibi ek özellikleri ve farklılıkları var? Yerel sınıfın bir nesnesi, içinde bildirildiği yöntemin veya bloğun dışında yaratılamaz. generatePhoneNumber()Rastgele bir telefon numarası üretecek ve bir nesne döndürecek bir yönteme ihtiyacımız olduğunu hayal edin PhoneNumber. Mevcut durumumuzda, doğrulayıcı sınıfımızda böyle bir yöntem oluşturamıyoruz:
public class PhoneNumberValidator {

   public void validatePhoneNumber(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;
           }
       }

       // ...number validation code
   }

   // Error! The compiler does not recognize the PhoneNumber class
   public PhoneNumber generatePhoneNumber() {

   }

}
Yerel sınıfların bir diğer önemli özelliği de yerel değişkenlere ve yöntem parametrelerine erişebilmeleridir. Unutmuş olmanız ihtimaline karşı, bir yöntem içinde bildirilen bir değişken "yerel" değişken olarak bilinir. String usCountryCodeYani, herhangi bir nedenle metot içinde yerel bir değişken yaratırsak validatePhoneNumber(), ona yerel sınıftan erişebiliriz PhoneNumber. Ancak, programda kullanılan dilin sürümüne bağlı olarak pek çok incelik vardır. Dersin başında, örneklerden birinin kodunun Java 7'de derlenmeyebileceğini not ettik, hatırladınız mı? Şimdi bunun nedenlerine bakalım :) Java 7'de, yerel bir sınıf, yerel bir değişkene veya yöntem parametresine yalnızca yöntemde olduğu gibi bildirilirse erişebilir :final
public void validatePhoneNumber(String number) {

   String usCountryCode = "+1";

   class PhoneNumber {

       private String phoneNumber;

       // Error! The method parameter must be declared as final!
       public PhoneNumber() {
           this.phoneNumber = number;
       }

       public void printUsCountryCode() {

           // Error! The local variable must be declared as final!
           System.out.println(usCountryCode);
       }

   }

   // ...number validation code
}
Burada derleyici iki hata üretir. Ve burada her şey yolunda:
public void validatePhoneNumber(final String number) {

   final String usCountryCode = "+1";

    class PhoneNumber {

       private String phoneNumber;


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

       public void printUsCountryCode() {

           System.out.println(usCountryCode);
       }

    }

   // ...number validation code
}
Artık dersin başındaki kodun neden derlenmediğini biliyorsunuz: Java 7'de yerel bir sınıfın yalnızca finalyöntem parametrelerine ve finalyerel değişkenlere erişimi vardır. Java 8'de yerel sınıfların davranışı değişti. Dilin bu sürümünde, yerel bir sınıf yalnızca finalyerel değişkenlere ve parametrelere değil, aynı zamanda effective-final. Effective-finaldeğeri başlatıldığından beri değişmeyen bir değişkendir. usCountryCodeÖrneğin, Java 8'de, değişken olmasa bile konsolda kolayca gösterebiliyoruz final. Önemli olan değerinin değişmemesidir. Aşağıdaki örnekte, her şey olması gerektiği gibi çalışıyor:
public void validatePhoneNumber(String number) {

  String usCountryCode = "+1";

    class PhoneNumber {

       public void printUsCountryCode() {

           // Java 7 would produce an error here
           System.out.println(usCountryCode);
       }

    }

   // ...number validation code
}
Ancak, başlatmanın hemen ardından değişkenin değerini değiştirirsek, kod derlenmez.
public void validatePhoneNumber(String number) {

  String usCountryCode = "+1";
  usCountryCode = "+8";

    class PhoneNumber {

       public void printUsCountryCode() {

           // Error!
           System.out.println(usCountryCode);
       }

    }

   // ...number validation code
}
Yerel bir sınıfın, iç sınıf kavramının bir alt türü olmasına şaşmamalı! Ortak özellikleri de vardır. Yerel bir sınıf, dış sınıfın tüm (hatta özel) alanlarına ve yöntemlerine erişebilir: hem statik hem de statik olmayan. String phoneNumberRegexÖrneğin, doğrulayıcı sınıfımıza statik bir alan ekleyelim :
public class PhoneNumberValidator {

   private static String phoneNumberRegex = "[^0-9]";

   public void validatePhoneNumber(String phoneNumber) {
       class PhoneNumber {

           // ......
       }
   }
}
Doğrulama bu statik değişken kullanılarak gerçekleştirilecektir. [^0-9]Yöntem, iletilen dizenin " " normal ifadesiyle (yani, 0'dan 9'a kadar bir rakam olmayan herhangi bir karakter) eşleşmeyen karakterler içerip içermediğini kontrol eder . Bu değişkene yerel sınıftan kolayca erişebiliriz PhoneNumber. Örneğin, bir alıcı yazın:
public String getPhoneNumberRegex() {

   return phoneNumberRegex;
}
Yerel sınıflar, herhangi bir statik üye tanımlayamadıkları veya bildiremedikleri için iç sınıflara benzer. Statik yöntemlerdeki yerel sınıflar, yalnızca çevreleyen sınıfın statik üyelerine başvurabilir. Örneğin, çevreleyen sınıfın bir değişkenini (alanını) statik olarak tanımlamazsanız, Java derleyicisi bir hata oluşturur: "Statik olmayan değişkene statik bir bağlamdan başvurulamaz." Yerel sınıflar statik değildir, çünkü çevreleyen bloktaki örnek üyelere erişimleri vardır. Sonuç olarak, çoğu statik bildirim türünü içeremezler. Bir bloğun içinde bir arabirim bildiremezsiniz: arabirimler doğası gereği statiktir. Bu kod derlenmiyor:
public class PhoneNumberValidator {
   public static void validatePhoneNumber(String number) {
       interface I {}

       class PhoneNumber implements I{
           private String phoneNumber;

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

       // ...number validation code
   }
}
Ancak, bir dış sınıf içinde bir arabirim bildirilirse, PhoneNumbersınıf onu uygulayabilir:
public class PhoneNumberValidator {
   interface I {}

   public static void validatePhoneNumber(String number) {

       class PhoneNumber implements I{
           private String phoneNumber;

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

       // ...number validation code
   }
}
Statik başlatıcılar (başlatma blokları) veya arabirimler yerel sınıflarda bildirilemez. Ancak, sabit değişkenler ( ) olmaları koşuluyla, yerel sınıfların statik üyeleri olabilir static final. Ve artık yerel sınıfları biliyorsunuz millet! Gördüğünüz gibi, sıradan iç sınıflardan birçok farklılıkları var. Nasıl çalıştıklarını anlamak için dilin belirli sürümlerinin özelliklerini bile araştırmak zorunda kaldık :) Bir sonraki derste, iç içe geçmiş sınıfların son grubu olan anonim iç sınıflardan bahsedeceğiz. çalışmalarınızda İyi şanslar! :)
Yorumlar
  • Popüler
  • Yeni
  • Eskimiş
Yorum bırakmak için giriş yapmalısınız
Bu sayfada henüz yorum yok