JavaRush /Блоги Java /Random-TG /Синфҳои дохилӣ дар усули маҳаллӣ

Синфҳои дохилӣ дар усули маҳаллӣ

Дар гурӯҳ нашр шудааст
Салом! Биёед дар бораи як навъи дигари синфи лона гап занем. Махз, дар бораи синфҳои маҳаллӣ (Усули синфҳои дохorи маҳаллӣ). Аввалин чизе, ки шумо бояд пеш аз таҳсил дар хотир дошта бошед, ҷои онҳо дар сохтори синфҳои лона аст. Дар асоси диаграммаи мо, мо метавонем фаҳмем, ки синфҳои маҳаллӣ як зергурӯҳи синфҳои дохилӣ мебошанд, ки мо дар бораи онҳо дар яке аз маводи қаблӣДарсҳои дохилӣ бо усули маҳаллӣ - 2 муфассал сӯҳбат карда будем . Бо вуҷуди ин, синфҳои маҳаллӣ аз синфҳои дохилӣ як қатор хусусиятҳо ва фарқиятҳои муҳим доранд. Калид дар эъломияи онҳост: Синфи маҳаллӣ танҳо дар блоки code эълон карда мешавад. Аксар вақт - дар дохor баъзе усули синфи беруна. Масалан, он метавонад чунин бошад:
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 валидации номера
   }
}
МУҲИМ!Агар шумо Java 7 насб карда бошед, ин code ҳангоми часбондан ба IDEA тартиб дода намешавад.Дар бораи сабабҳои ин дар охири лексия сӯҳбат хоҳем кард. Бо чанд сухан, кори синфхои махаллй ба versionи забон хеле вобаста аст. Агар ин code барои шумо тартиб надиҳад, шумо метавонед versionи забонро дар IDEA ба Java 8 иваз кунед ё finalба параметри метод калима илова кунед, то ин ки чунин бошад: validatePhoneNumber(final String number). Пас аз ин ҳама чиз кор хоҳад кард. Ин як барномаи хурд аст - санҷиши рақами телефон. Усули он validatePhoneNumber()сатрро ҳамчун вуруд мегирад ва муайян мекунад, ки оё он рақами телефон аст. Ва дар дохor ин усул мо синфи маҳаллии худро эълон кардем PhoneNumber. Шояд шумо як саволи мантиқӣ дошта бошед: чаро? Чаро синфро дар дохor метод эълон кардан лозим аст? Чаро синфи муқаррарии дохorро истифода набаред? Дар ҳақиқат, метавонист ин корро кунад: синфро PhoneNumberдохилӣ созед. Чизи дигар ин аст, ки тасмими ниҳоӣ аз сохтор ва ҳадафи барномаи шумо вобаста аст. Биёед мисоли худро аз лекция дар бораи синфҳои дохилӣ ба ёд орем:
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!");
       }
   }
}
Дар он мо HandleBarяк синфи дохorи велосипедро (дастгоҳҳо) сохтем. Фарқият чист? Пеш аз ҳама, дар истифодаи синф. Синфи HandleBarмисоли дуюм нисбат PhoneNumberба намунаи аввал як сохтори мураккабтар аст. Аввалан, y HandleBarдорои усулҳои оммавӣ мебошад rightва left(сетер ва қабулкунанда нестанд). Сониян, мо наметавонем пешакӣ пешгӯӣ кунем, ки Bicycleон ба куҷо лозим аст ва синфи берунии он - инҳо метавонанд даҳҳо ҷойҳо ва усулҳои гуногун бошанд, ҳатто дар доираи як барнома. Аммо бо синф PhoneNumberҳама чиз хеле соддатар аст. Барномаи мо хеле содда аст. Он танҳо як функсия дорад - санҷидани он, ки рақам рақами телефон аст. Дар аксари ҳолатҳо, мо PhoneNumberValidatorҳатто як барномаи мустақил нест, балки танҳо як ҷузъи мантиқи иҷозат барои барномаи асосӣ хоҳад буд. Масалан, дар вебсайтҳои гуногун ҳангоми сабти ном аксар вақт аз шумо хоҳиш карда мешавад, ки рақами телефонро ворид кунед. Ва агар шумо ба ҷои рақамҳо ягон чизи бемаънӣ нависед, сайт хатогӣ нишон медиҳад: "Ин рақами телефон нест!" Барои фаъолияти чунин сайт (ё дурусттараш, механизми иҷозати корбар), таҳиягарони он метавонанд аналоги моро дар code дохил кунанд PhoneNumberValidator. Ба ибораи дигар, мо як синфи берунӣ бо як метод дорем, ки дар як ҷо дар барнома истифода мешавад ва дар ҷои дигар. Ва агар ин тавр бошад, пас дар он ҳеҷ чиз тағир намеёбад: як усул кори худро иҷро мекунад - ҳамааш ҳамин аст. Дар ин ҳолат, азбаски тамоми мантиқи кор дар як усул ҷамъ оварда мешавад, дар он ҷо фарогирии синфи иловагӣ хеле қулайтар ва дурусттар хоҳад буд. Он ба ҷуз аз гетер ва сетер усулҳои худро надорад. Мо аслан танҳо ба маълумоти созанда аз он ниёз дорем. Он дар дигар усулҳо истифода намешавад. Аз ин рӯ, ҳеҷ асосе барои васеъ кардани маълумот дар бораи он берун аз усули ягонае, ки он истифода мешавад, вуҷуд надорад. Мо мисоли эълони синфи маҳаллиро дар метод додем, аммо ин ягона имкон нест. Онро метавон танҳо дар блоки code эълон кард:
public class PhoneNumberValidator {

   {
       class PhoneNumber {

           private String phoneNumber;

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

   }

   public void validatePhoneNumber(String phoneNumber) {


       //...code валидации номера
   }
}
Ё ҳатто дар як ҳалқа 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 валидации номера
   }
}
Аммо чунин ҳолатҳо хеле каманд. Дар аксари ҳолатҳо, эъломия ҳанӯз дар дохor усул рух медиҳад. Инак, бо эълон сару кор доштем, дар бораи «фалсафа» хам сухбат кардем :) Синфхои махаллй аз синфхои дохилй боз чй хусусият ва тафовут доранд? Объекти синфи маҳаллиро берун аз усул ё блоке, ки дар он эълон шудааст, эҷод кардан мумкин нест. Тасаввур кунед, ки ба мо усуле лозим аст generatePhoneNumber(), ки рақами телефони тасодуфиро тавлид кунад ва PhoneNumber. Мо дар вазъияти кунунӣ чунин усулро дар синфи валидатори худ эҷод карда наметавонем:
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() {

   }

}
Хусусияти дигари муҳими синфҳои маҳаллӣ ин қобorяти дастрасӣ ба тағирёбандаҳои маҳаллӣ ва параметрҳои метод мебошад. Агар шумо фаромӯш карда бошед, "маҳаллӣ" тағирёбандаест, ки дар дохor усул эълон шудааст. String russianCountryCodeЯъне, агар мо дар дохor усул барои баъзе мақсадҳои худ як тағирёбандаи маҳаллӣ эҷод кунем validatePhoneNumber(), мо метавонем онро аз синфи маҳаллӣ дастрас кунем PhoneNumber. Бо вуҷуди ин, дар ин ҷо нозукиҳои зиёде мавҷуданд, ки аз versionи забони дар барнома истифодашуда вобастаанд. Дар оғози лексия мо қайд кардем, ки codeи яке аз мисолҳо дар Java 7 тартиб дода нашавад, дар хотир доред? Акнун биёед ба сабабҳои ин назар андозем :) Дар Java 7, синфи маҳаллӣ метавонад танҳо ба тағирёбанда ё параметри метод дастрасӣ пайдо кунад, агар онҳо дар метод чунин эълон карда шаванд 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 валидации номера
}
Дар ин ҷо компилятор ду хатогӣ дод. Аммо дар ин ҷо ҳама чиз ба тартиб аст:
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 валидации номера
}
Акнун шумо медонед, ки чаро code дар аввали лексия тартиб наёфтааст: синфи маҳаллӣ дар Java 7 танҳо ба finalпараметрҳои -метод ва final-тағирёбандаҳои маҳаллӣ дастрасӣ дорад. Дар Java 8 рафтори синфҳои маҳаллӣ тағйир ёфт. Дар ин versionи забон, синфи маҳаллӣ на танҳо ба finalтағирёбандаҳо ва параметрҳои маҳаллӣ, балки ба effective-final. Effective-finalтағирёбандаест, ки аз замони оғозёбӣ арзиши он тағйир наёфтааст. Масалан, дар Java 8 мо метавонем ба осонӣ тағирёбандаро дар консол намоиш диҳем russianCountryCode, ҳатто агар он набошад final. Чизи асосй он аст, ки вай маънои онро тагьир намедихад. Дар ин мисол, ҳама чиз тавре кор мекунад, ки бояд бошад:
public void validatePhoneNumber(String number) {

  String russianCountryCode = "+7";

    class PhoneNumber {

       public void printRussianCountryCode() {

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

    }

   //...code валидации номера
}
Аммо агар мо арзиши тағирёбандаро фавран пас аз оғозёбӣ тағир диҳем, code тартиб дода намешавад.
public void validatePhoneNumber(String number) {

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

    class PhoneNumber {

       public void printRussianCountryCode() {

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

    }

   //...code валидации номера
}
Аммо бесабаб нест, ки синфи маҳаллӣ як зернавъи синфи дохилӣ аст! Онҳо инчунин нуктаҳои умумӣ доранд. Синфи маҳаллӣ ба ҳама майдонҳо ва усулҳои синфи берунӣ (ҳатто хусусӣ) дастрасӣ дорад: ҳам статикӣ ва ҳам ғайристатикӣ. Масалан, биёед ба синфи валидатори худ майдони статикӣ илова кунем String phoneNumberRegex:
public class PhoneNumberValidator {

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

   public void validatePhoneNumber(String phoneNumber) {
       class PhoneNumber {

           //......
       }
   }
}
Тасдиқ бо истифода аз ин тағирёбандаи статикӣ анҷом дода мешавад. Усул месанҷад, ки оё сатри ба он интиқолёфта дорои аломатҳое мебошад, ки ба ифодаи муқаррарии " " мувофиқат намекунанд [^0-9](яъне аломат рақами аз 0 то 9 нест). Мо метавонем ба осонӣ ба ин тағирёбанда аз синфи маҳаллӣ дастрасӣ пайдо кунем PhoneNumber. Масалан, қабулкунанда нависед:
public String getPhoneNumberRegex() {

   return phoneNumberRegex;
}
Синфҳои маҳаллӣ ба синфҳои дохилӣ монанданд, зеро онҳо наметавонанд ягон аъзои статикиро муайян ё эълон кунанд. Синфҳои маҳаллӣ дар усулҳои статикӣ метавонанд танҳо ба аъзои статикии синфи фарогир муроҷиат кунанд. Масалан, агар шумо тағирёбандаи (майдони) синфи иҳотакунандаро ҳамчун статикӣ муайян накунед, компилятори Java хато мекунад: "Ба тағирёбандаи ғайристатикӣ аз контексти статикӣ истинод кардан мумкин нест." Синфҳои маҳаллӣ статикӣ нестанд, зеро онҳо ба аъзои мисоли блоки дорои дастрасӣ доранд. Аз ин рӯ, онҳо наметавонанд аксари намудҳои эъломияҳои статикиро дар бар гиранд. Шумо наметавонед интерфейсро дар дохor блок эълон кунед; Интерфейсҳо табиати статикӣ доранд. Ин code тартиб дода намешавад:
public class PhoneNumberValidator {
   public static void validatePhoneNumber(String number) {
       interface I {}

       class PhoneNumber implements I{
           private String phoneNumber;

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

       //...code валидации номера
   }
}
Аммо агар интерфейс дар дохor синфи берунӣ эълон карда шавад, синф PhoneNumberметавонад онро амалӣ кунад:
public class PhoneNumberValidator {
   interface I {}

   public static void validatePhoneNumber(String number) {

       class PhoneNumber implements I{
           private String phoneNumber;

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

       //...code валидации номера
   }
}
Синфҳои маҳаллӣ наметавонанд инициализаторҳои статикӣ (блокҳои ибтидоӣ) ё интерфейсҳоро эълон кунанд. Аммо синфҳои маҳаллӣ метавонанд аъзои статикӣ дошта бошанд, ба шарте ки онҳо тағирёбандаҳои доимӣ бошанд ( static final). Инҳоянд, синфҳои маҳаллӣ! Тавре ки шумо мебинед, онҳо аз синфҳои дохилӣ фарқиятҳои зиёд доранд. Мо ҳатто маҷбур шудем, ки ба хусусиятҳои versionи забон ғарқ шавем, то бифаҳмем, ки онҳо чӣ гуна кор мекунанд :) Дар лексияи навбатӣ, мо дар бораи синфҳои дохorи беном - гурӯҳи охирини синфҳои лона сӯҳбат хоҳем кард. Муваффақият дар таҳсилатон! :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION