CodeGym /Blog Jawa /Acak /Kelas batin kanthi metode lokal
John Squirrels
tingkat
San Francisco

Kelas batin kanthi metode lokal

Diterbitake ing grup
Hi! Ayo dadi pirembagan bab jinis liyane nested kelas. Aku ngomong babagan kelas lokal (kelas batin metode-lokal). Sadurunge nyilem, kita kudu ngelingi panggonane ing struktur kelas nested. Kelas batin ing metode lokal - 2Saka diagram kita, kita bisa ndeleng manawa kelas lokal minangka subspesies saka kelas njero, sing wis dibahas kanthi rinci ing materi sadurunge . Nanging, kelas lokal duwe sawetara fitur penting lan beda saka kelas batin biasa. Ingkang utama yaiku ing deklarasi: Kelas lokal diumumake mung ing blok kode. Paling asring, deklarasi iki ana ing sawetara metode kelas njaba. Contone, bisa uga katon kaya iki:

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
   }
}
PENTING!Yen sampeyan wis nginstal Java 7, kode iki ora bakal dikompilasi nalika ditempelake menyang IDEA. Kita bakal ngomong babagan alasan iki ing pungkasan pelajaran. Singkatipun, cara kerja kelas lokal gumantung banget marang versi basa kasebut. Yen kode iki ora kompilasi kanggo sampeyan, sampeyan bisa ngganti versi basa ing IDEA kanggo Java 8, utawa nambah tembung finalkanggo parameter cara supaya katon kaya iki validatePhoneNumber(final String number):. Sawise iku, kabeh bakal bisa. Iki minangka program cilik sing validasi nomer telpon. Cara kasebut validatePhoneNumber()njupuk senar minangka input lan nemtokake manawa iku nomer telpon. Lan ing cara iki, kita ngumumake PhoneNumberkelas lokal kita. Sampeyan bisa uga takon apa sebabe. Yagene persis kita bakal ngumumake kelas ing sawijining metode? Apa ora nggunakake kelas batin biasa? Bener, kita bisa nggawePhoneNumberkelas lan kelas batin. Nanging solusi pungkasan gumantung saka struktur lan tujuan program sampeyan. Ayo kelingan conto saka pawulangan babagan kelas batin:

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!");
       }
   }
}
Ing kono, kita nggawe HandleBarkelas jero sepeda. Apa bedane? Kaping pisanan, cara kelas digunakake beda. Kelas HandleBaring conto kapindho minangka entitas sing luwih rumit tinimbang PhoneNumberkelas ing conto pisanan. Pisanan, HandleBarduwe umum rightlan leftmetode (iki dudu setter / getters). Kapindho, iku mokal kanggo prédhiksi ing advance ngendi kita perlu lan Bicyclekelas njaba sawijining. Bisa uga ana puluhan panggonan lan cara sing beda-beda, sanajan ing program siji. Nanging kanthi PhoneNumberkelas, kabeh luwih gampang. Program kita prasaja banget. Wis mung siji waé: kanggo mriksa apa nomer iku nomer telpon bener. Ing kasus paling, kitaPhoneNumberValidatormalah ora bakal dadi program dewekan, nanging rodo bagéan saka logika wewenang kanggo program luwih gedhe. Contone, macem-macem situs web asring njaluk nomer telpon nalika pangguna ndhaptar. Yen sampeyan ngetik sawetara omong kosong tinimbang nomer, situs web bakal nglaporake kesalahan: "Iki dudu nomer telpon!" Pangembang situs web kasebut (utawa, mekanisme wewenang pangguna) bisa uga kalebu sing padha karo kitaPhoneNumberValidatoring kode sing. Ing tembung liyane, kita duwe siji kelas njaba karo siji cara, kang bakal digunakake ing sak panggonan ing program lan ora liya. Lan yen digunakake, mula ora ana sing bakal diganti: siji cara nindakake tugase - lan iku. Ing kasus iki, amarga kabeh logika diklumpukake dadi siji cara, iku bakal luwih trep lan tepat kanggo encapsulate kelas tambahan ana. Ora ana cara dhewe kajaba getter lan setter. Ing kasunyatan, kita mung butuh data saka konstruktor. Iku ora melu ing cara liyane. Mulane, ora ana alesan kanggo njupuk informasi babagan iki ing njaba mung cara sing digunakake. Kita uga menehi conto ing ngendi kelas lokal diumumake kanthi cara, nanging iki ora mung siji-sijine pilihan. Bisa diumumake mung ing blok kode:

public class PhoneNumberValidator {
  
   {
       class PhoneNumber {

           private String phoneNumber;

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

   }

   public void validatePhoneNumber(String phoneNumber) {

      
       // ...number validation code
   }
}
Utawa malah ing fordaur ulang!

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
   }
}
Nanging kasus kaya mengkono arang banget. Umume kasus, deklarasi bakal kedadeyan ing metode kasebut. Dadi, kita nemtokake deklarasi, lan kita uga ngomong babagan "filsafat" :) Apa fitur tambahan lan bedane kelas lokal dibandhingake karo kelas batin? Objek saka kelas lokal ora bisa digawe ing njaba metode utawa blok sing diumumake. Mbayangno yen kita butuh generatePhoneNumber()cara sing bakal ngasilake nomer telpon acak lan ngasilake PhoneNumberobyek. Ing kahanan saiki, kita ora bisa nggawe metode kasebut ing kelas validator:

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() {

   }

}
Fitur penting liyane saka kelas lokal yaiku kemampuan kanggo ngakses variabel lokal lan paramèter metode. Yen sampeyan lali, variabel sing diumumake ing sawijining metode dikenal minangka variabel "lokal". Yaiku, yen kita nggawe String usCountryCodevariabel lokal ing validatePhoneNumber()metode sawetara alasan, kita bisa ngakses saka PhoneNumberkelas lokal. Nanging, ana akeh subtleties sing gumantung saka versi basa sing digunakake ing program kasebut. Ing wiwitan pawulangan, kita nyathet yen kode kanggo salah sawijining conto bisa uga ora dikompilasi ing Jawa 7, elinga? Saiki ayo nimbang alasan kanggo iki :) Ing Jawa 7, kelas lokal bisa ngakses variabel lokal utawa parameter metode mung yen diumumake kaya finaling metode:

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
}
Ing kene compiler ngasilake loro kesalahan. Lan kabeh ana ing kene:

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
}
Saiki sampeyan ngerti kenapa kode saka wiwitan pawulangan ora bakal dikompilasi: ing Jawa 7, kelas lokal mung nduweni akses menyang finalparameter metode lan finalvariabel lokal. Ing Jawa 8, solah bawane kelas lokal wis owah. Ing versi basa iki, kelas lokal nduweni akses ora mung menyang finalvariabel lan parameter lokal, nanging uga kanggo sing effective-final. Effective-finalyaiku variabel sing nilaine ora owah wiwit wiwitan. Contone, ing Jawa 8, kita bisa kanthi gampang nampilake usCountryCodevariabel ing console, sanajan ora final. Sing penting regane ora owah. Ing conto ing ngisor iki, kabeh bisa digunakake kaya sing dikarepake:

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
}
Nanging yen kita ngganti nilai variabel sanalika sawise initialization, kode ora bakal kompilasi.

public void validatePhoneNumber(String number) {

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

    class PhoneNumber {

       public void printUsCountryCode() {

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

    }

   // ...number validation code
}
Ora ana wonder yen kelas lokal minangka subspesies saka konsep kelas batin! Dheweke uga duwe ciri umum. Kelas lokal nduweni akses menyang kabeh (malah pribadi) lapangan lan cara saka kelas njaba: loro statis lan non-statis. Contone, ayo nambah String phoneNumberRegexkolom statis menyang kelas validator:

public class PhoneNumberValidator {

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

   public void validatePhoneNumber(String phoneNumber) {
       class PhoneNumber {
          
           // ......
       }
   }
}
Validasi bakal ditindakake nggunakake variabel statis iki. Cara mriksa yen string liwati ngemot karakter sing ora cocog karo ekspresi reguler " [^0-9]" (yaiku karakter apa wae sing dudu digit saka 0 nganti 9). Kita bisa kanthi gampang ngakses variabel iki saka PhoneNumberkelas lokal. Contone, nulis getter:

public String getPhoneNumberRegex() {
  
   return phoneNumberRegex;
}
Kelas lokal padha karo kelas njero, amarga ora bisa nemtokake utawa nyatakake anggota statis. Kelas lokal ing cara statis mung bisa ngrujuk anggota statis saka kelas enclosing. Contone, yen sampeyan ora nemtokake variabel (bidang) saka kelas enclosing minangka statis, compiler Java ngasilake kesalahan: "Variabel non-statis ora bisa dirujuk saka konteks statis." Kelas lokal ora statis, amarga padha duwe akses kanggo anggota Kayata ing pemblokiran enclosing. Akibaté, padha ora bisa ngemot paling jinis deklarasi statis. Sampeyan ora bisa ngumumake antarmuka ing blok: antarmuka pancen statis. Kode iki ora kompilasi:

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
   }
}
Nanging yen antarmuka diumumake ing njero kelas njaba, PhoneNumberkelas kasebut bisa ngetrapake:

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
   }
}
Inisialisasi statis (pamblokiran wiwitan) utawa antarmuka ora bisa diumumake ing kelas lokal. Nanging kelas lokal bisa duwe anggota statis, kasedhiya sing variabel pancet ( static final). Lan saiki sampeyan ngerti babagan kelas lokal, wong! Nalika sampeyan bisa ndeleng, padha duwe akeh beda saka kelas utama biasa. Kita malah kudu delve menyang fitur saka versi tartamtu saka basa supaya ngerti carane padha bisa digunakake :) Ing pawulangan sabanjuré, kita bakal pirembagan bab kelas njero anonim — klompok pungkasan nested kelas. Good luck ing pasinaon! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION