JavaRush /Blog Jawa /Random-JV /Kelas batin ing metode lokal

Kelas batin ing metode lokal

Diterbitake ing grup
Hello! Ayo dadi pirembagan bab jinis liyane nested kelas. Yaiku babagan kelas lokal (Metode local inner classes). Wangsulan: Bab ingkang pisanan sampeyan kudu elinga sadurunge sinau iku panggonan ing struktur kelas nested. Kelas batin ing metode lokal - 2Adhedhasar diagram kita, kita bisa ngerti yen kelas lokal minangka subtipe saka kelas internal, sing kita rembugan kanthi rinci ing salah sawijining materi sadurunge . Nanging, kelas lokal duwe sawetara fitur penting lan beda saka kelas internal. Kuncine ana ing deklarasi: Kelas lokal diumumake mung ing blok kode. Paling asring - ing sawetara cara saka kelas eksternal. 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;
           }
       }

       //...code валидации номера
   }
}
PENTING!Kode iki ora bakal dikompilasi nalika ditempelake menyang IDEA yen sampeyan wis nginstal Java 7. Kita bakal ngomong babagan alasan iki ing pungkasan kuliah. Ing sawetara tembung, karya kelas lokal gumantung banget marang versi basa. Yen kode iki ora kompilasi kanggo sampeyan, sampeyan bisa ngganti versi basa ing IDEA kanggo Jawa 8, utawa nambah tembung finalkanggo parameter cara supaya katon kaya iki validatePhoneNumber(final String number):. Sawise iki kabeh bakal bisa. Iki minangka program cilik - validator nomer telpon. Cara kasebut validatePhoneNumber()njupuk senar minangka input lan nemtokake manawa iku nomer telpon. Lan ing njero metode iki kita ngumumake kelas lokal kita PhoneNumber. Sampeyan bisa uga duwe pitakonan logis: kenapa? Napa ngumumake kelas ing metode? Apa ora nggunakake kelas batin biasa? Pancen, siji bisa nindakake iki: nggawe kelas PhoneNumberinternal. Bab liya yaiku keputusan pungkasan gumantung saka struktur lan tujuan program sampeyan. Ayo elinga conto saka ceramah babagan 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!");
   }

   public class HandleBar {

       public void right() {
           System.out.println("Steering wheel to the right!");
       }

       public void left() {

           System.out.println("Steering wheel to the left!");
       }
   }
}
Ing kono kita nggawe HandleBar(stang) kelas internal sepeda. Apa bedane? Kaping pisanan, nggunakake kelas. Kelas HandleBarsaka conto kapindho minangka entitas sing luwih rumit tinimbang PhoneNumbersaka sing pisanan. Pisanan, y HandleBarduwe metode umum rightlan left(ora dadi setter lan getter). Kapindho, kita ora bisa prédhiksi luwih dhisik ing ngendi Bicyclekita butuh lan kelas eksternal - iki bisa dadi puluhan papan lan cara sing beda, sanajan ing program sing padha. Nanging kanthi kelas, PhoneNumberkabeh luwih gampang. Program kita prasaja banget. Wis mung siji fungsi - kanggo mriksa apa nomer iku nomer telpon. Umume kasus, program kita PhoneNumberValidatorora bakal dadi program mandiri, nanging mung dadi bagean ing logika wewenang kanggo program utama. Contone, ing macem-macem situs web, nalika ndhaptar, sampeyan asring dijaluk ngetik nomer telpon. Lan yen sampeyan ngetik sawetara omong kosong tinimbang nomer, situs bakal nampilake kesalahan: "Iki dudu nomer telpon!" Kanggo operasi situs kasebut (utawa, mekanisme wewenang pangguna), pangembang bisa nyakup analog saka kita ing kode kasebut PhoneNumberValidator. Ing tembung liyane, kita duwe siji kelas external karo siji cara sing bakal digunakake ing sak panggonan ing program lan ora ono liyane. Lan yen ana, mula ora ana sing bakal diganti: siji cara nindakake tugase - iku kabeh. Ing kasus iki, amarga kabeh logika karya diklumpukake ing siji cara, iku bakal luwih trep lan bener kanggo encapsulate kelas tambahan ana. Ora duwe cara dhewe kajaba getter lan setter. Kita mung butuh data konstruktor saka iku. Ora digunakake ing cara liya. Mulane, ora ana alesan kanggo ngluwihi informasi babagan iki ngluwihi cara siji sing digunakake. We menehi conto deklarasi kelas lokal ing cara, nanging iki ora mung kamungkinan. 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) {


       //...code валидации номера
   }
}
Utawa malah ing loop 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;
               }
           }

           //...Howая-то логика
       }

       //...code валидации номера
   }
}
Nanging kasus kaya mengkono arang banget. Umume kasus, deklarasi isih bakal kedadeyan ing metode kasebut. Dadi, kita ngurusi woro-woro kasebut, kita uga ngomong babagan "filsafat" :) Apa fitur lan beda liyane sing ana ing kelas lokal saka kelas internal? Objek kelas lokal ora bisa digawe ing njaba metode utawa blok sing diumumake. Mbayangno kita kudu cara generatePhoneNumber()sing ngasilake nomer telpon acak lan ngasilake a PhoneNumber. Kita ora bakal bisa nggawe metode kasebut ing kelas validator ing kahanan saiki:
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;
           }
       }

       //...code валидации номера
   }

   //ошибка! компилятор не понимает, что это за класс - PhoneNumber
   public PhoneNumber generatePhoneNumber() {

   }

}
Fitur penting liyane saka kelas lokal yaiku kemampuan kanggo ngakses variabel lokal lan paramèter metode. Yen sampeyan kelalen, "lokal" minangka variabel sing diumumake ing sawijining metode. String russianCountryCodeYaiku, yen kita nggawe variabel lokal ing sawijining metode kanggo sawetara tujuan kita validatePhoneNumber(), kita bisa ngakses saka kelas lokal PhoneNumber. Nanging, ana akeh subtleties ing kene sing gumantung saka versi basa sing digunakake ing program kasebut. Ing wiwitan kuliah, kita nggawe cathetan yen kode ing salah sawijining conto bisa uga ora dikompilasi ing Jawa 7, elinga? Saiki ayo goleki alasan kanggo iki :) Ing Jawa 7, kelas lokal mung bisa ngakses variabel lokal utawa parameter metode yen diumumake ing metode minangka final:
public void validatePhoneNumber(String number) {

   String russianCountryCode = "+7";

   class PhoneNumber {

       private String phoneNumber;

       //ошибка! параметр метода должен быть объявлен How final!
       public PhoneNumber() {
           this.phoneNumber = number;
       }

       public void printRussianCountryCode() {

           //ошибка! локальная переменная должна быть объявлена How final!
           System.out.println(russianCountryCode);
       }

   }

   //...code валидации номера
}
Kene compiler mbuwang loro kasalahan. Nanging ing kene kabeh ana ing urutan:
public void validatePhoneNumber(final String number) {

   final String russianCountryCode = "+7";

    class PhoneNumber {

       private String phoneNumber;


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

       public void printRussianCountryCode() {

           System.out.println(russianCountryCode);
       }

    }

   //...code валидации номера
}
Saiki sampeyan ngerti alesan kenapa kode ing wiwitan kuliah ora dikompilasi: kelas lokal ing Jawa 7 mung nduweni akses menyang finalparameter -method lan finalvariabel -local. Ing Jawa 8, solah bawane kelas lokal wis owah. Ing versi basa iki, kelas lokal nduweni akses ora mung kanggo finalvariabel lan parameter lokal, nanging uga kanggo effective-final. Effective-finalyaiku variabel sing nilaine ora owah wiwit wiwitan. Contone, ing Jawa 8 kita bisa kanthi gampang nampilake variabel menyang console russianCountryCode, sanajan ora final. Sing utama yaiku ora ngganti maknane. Ing conto iki, kabeh tumindak kaya sing dikarepake:
public void validatePhoneNumber(String number) {

  String russianCountryCode = "+7";

    class PhoneNumber {

       public void printRussianCountryCode() {

           //в Java 7 здесь была бы ошибка
           System.out.println(russianCountryCode);
       }

    }

   //...code валидации номера
}
Nanging yen kita ngganti nilai variabel sanalika sawise initialization, kode ora bakal kompilasi.
public void validatePhoneNumber(String number) {

  String russianCountryCode = "+7";
  russianCountryCode = "+8";

    class PhoneNumber {

       public void printRussianCountryCode() {

           //error!
           System.out.println(russianCountryCode);
       }

    }

   //...code валидации номера
}
Nanging ora kanggo apa-apa sing kelas lokal minangka subtipe saka kelas internal! Dheweke uga duwe titik umum. Kelas lokal nduweni akses menyang kabeh (malah pribadi) lapangan lan cara saka kelas njaba: loro statis lan non-statis. Contone, ayo nambah kolom statis menyang kelas validator String phoneNumberRegex:
public class PhoneNumberValidator {

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

   public void validatePhoneNumber(String phoneNumber) {
       class PhoneNumber {

           //......
       }
   }
}
Validasi bakal ditindakake nggunakake variabel statis iki. Cara kasebut mriksa manawa string sing diterusake ngemot karakter sing ora cocog karo ekspresi reguler " [^0-9]" (yaiku, karakter kasebut dudu angka saka 0 nganti 9). Kita bisa kanthi gampang ngakses variabel iki saka kelas lokal PhoneNumber. 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 duwe akses menyang anggota conto blok sing ngemot. Mulane, ora bisa ngemot akeh jinis deklarasi statis. Sampeyan ora bisa ngumumake antarmuka ing blok; antarmuka sing statis ing alam. Kode iki ora bakal dikompilasi:
public class PhoneNumberValidator {
   public static void validatePhoneNumber(String number) {
       interface I {}

       class PhoneNumber implements I{
           private String phoneNumber;

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

       //...code валидации номера
   }
}
Nanging yen antarmuka diumumake ing njero kelas njaba, kelas kasebut PhoneNumberbisa ngetrapake:
public class PhoneNumberValidator {
   interface I {}

   public static void validatePhoneNumber(String number) {

       class PhoneNumber implements I{
           private String phoneNumber;

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

       //...code валидации номера
   }
}
Kelas lokal ora bisa ngumumake wiwitan statis (pamblokiran wiwitan) utawa antarmuka. Nanging kelas lokal bisa duwe anggota statis, kasedhiya variabel pancet ( static final). Sing apa padha, kelas lokal! Nalika sampeyan bisa ndeleng, padha duwe akeh beda saka kelas internal. Kita malah kudu nyilem menyang fitur versi basa kanggo ngerti cara kerjane :) Ing kuliah sabanjure, kita bakal ngomong babagan kelas internal anonim - klompok pungkasan kelas nested. Good luck kanggo sinau! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION