JavaRush /Блоги Java /Random-TG /Ниҳоӣ, доимӣ ва тағирнопазир дар Java

Ниҳоӣ, доимӣ ва тағирнопазир дар Java

Дар гурӯҳ нашр шудааст
Салом! Калимаи "тағйирдиҳанда" аллакай ба шумо шинос аст. Ҳадди ақал, шумо бо тағирдиҳандаҳои дастрасӣ (оммавӣ, хусусӣ) ва тағирдиҳандаи статикӣ дучор омадаед. Имрӯз мо дар бораи тағирдиҳандаи махсуси ниҳоӣ сӯҳбат хоҳем кард . Гуфтан мумкин аст, ки он самтҳои барномаи моро "семент" мекунанд, ки ба мо рафтори доимӣ, якхела ва бетағйир лозим аст. Он метавонад дар се самти барномаи мо истифода шавад: синфҳо, усулҳо ва тағирёбандаҳо. Тағирнопазир дар Java: ниҳоӣ, доимӣ ва тағирнопазир - 2 Биёед онҳоро як ба як аз назар гузаронем. Агар эъломияи синф тағирдиҳандаи ниҳоӣ дошта бошад , ин маънои онро дорад, ки шумо аз ин синф мерос гирифта наметавонед. Дар лексияҳои қаблӣ мо як мисоли оддии меросро дидем: мо синфи волидайн Animalва ду синфи кӯдакон доштем - CatваDog
public class Animal {
}

public class Cat extends Animal {
   //..поля и методы класса Cat
}

public class Dog extends Animal {

   //..поля и методы класса Dog
}
Аммо, агар мо Animalтағирдиҳандаро барои синф муайян кунем, синфҳо ҳам finalнаметавонанд аз он мерос гиранд . CatDog
public final class Animal {

}

public class Cat extends Animal {

   //ошибка! Cannot inherit from final Animal
}
Компилятор фавран хато содир мекунад. Дар Java аллакай бисёр синфҳо мавҷуданд final. Машҳуртарини онҳо, ки шумо ҳамеша истифода мебаред, String. Илова бар ин, агар синф ҳамчун , эълон карда шавад final, ҳамаи усулҳои он низ ба final. Ин чӣ маъно дорад? Агар тағирдиҳанда барои метод муайян шуда бошад final, ин усулро бекор кардан мумкин нест. Масалан, мо синфе дорем Animal, ки методро муайян мекунад voice(). Бо вуҷуди ин, сагҳо ва гурбаҳо ба таври равшан "гӯянд". Аз ин рӯ, дар ҳар як синф - Catва Dog- мо методеро эҷод мекунем voice(), аммо мо онро ба таври дигар амалӣ хоҳем кард.
public class Animal {

   public void voice() {
       System.out.println("Voice!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void voice() {
       System.out.println("Woof!");
   }
}
Дар синфҳо Catва Dogмо усули синфи волидайнро бекор кардем. Ҳоло ҳайвон вобаста аз он ки an objectи синфӣ аст, садо хоҳад дод:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();

       cat.voice();
       dog.voice();
   }
}
Хулоса: Меов! Воф! Аммо, агар Animalмо методро дар синф voice()ҳамчун , эълон кунем final, онро дар синфҳои дигар дубора муайян кардан ғайриимкон аст:
public class Animal {

   public final void voice() {
       System.out.println("Voice!");
   }
}


public class Cat extends Animal {

   @Override
   public void voice() {//ошибка! final-метод не может быть переопределен!
       System.out.println("Meow!");
   }
}
Он гоҳ an objectҳои мо маҷбур мешаванд, ки усулро тавре истифода баранд voice(), ки он дар синфи волидайн муайян карда шудааст:
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   cat.voice();
   dog.voice();
}
Хулоса: Овоз! Овоз! Акнун дар бораи finalтағирёбандаҳо. Дар акси ҳол онҳо доимӣ номида мешаванд . Аввалан (ва муҳимтар аз ҳама), арзиши аввалине, ки ба доимӣ таъин шудааст, тағир додан мумкин нест. Он як бор ва то абад таъин карда мешавад.
public class Main {

   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;//ошибка! Нельзя присвоить новое meaning final-переменной!
   }
}
Собитро фавран оғоз кардан лозим нест. Инро дертар кардан мумкин аст. Аммо арзиши аввал таъиншуда то абад боқӣ мемонад.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;//так делать можно
}
Дуюм, ба номи тағирёбандаи мо диққат диҳед. Константаҳои Java конвенсияи дигари номгузорӣ доранд. Ин парвандаи шутур нест, ки мо одат кардаем. Дар мавриди тағирёбандаи муқаррарӣ, мо онро собитМисол меномем, аммо номи доимӣ бо ҳарфҳои калон навишта мешаванд ва дар байни калимаҳо (агар якчандтои онҳо бошанд) аломати зерхат гузошта мешавад - “МИСОЛ_МИСОЛ”. Чаро константаҳо лозиманд? Масалан, агар шумо ҳамеша дар барнома ягон арзиши доимиро истифода баред, онҳо муфид хоҳанд буд. Фарз мекунем, ки шумо тасмим гирифтед, ки ба таърих ворид шавед ва танҳо бозии "The Witcher 4" -ро нависед. Бозӣ бешубҳа ҳамеша номи қаҳрамони асосӣ - "Гералт аз Ривия" -ро истифода мебарад. Беҳтар аст, ки ин сатр ва номи қаҳрамонҳои дигарро ба доимӣ ҷудо кунед: арзише, ки ба шумо лозим аст, дар як ҷо нигоҳ дошта мешавад ва шумо бешубҳа ҳангоми навиштани он бори миллионум хато намекунед.
public class TheWitcher4 {

   private static final String GERALT_NAME = "Геральт из Ривии";
   private static final String YENNEFER_NAME = "Йеннифэр из Венгерберга";
   private static final String TRISS_NAME = "Трисс Меригольд";

   public static void main(String[] args) {

       System.out.println("Ведьмак 4");
       System.out.println("Это уже четвертая часть Ведьмака, а " + GERALT_NAME + " ниHow не определится кто ему" +
               " нравится больше: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("Но если вы никогда не играли в Ведьмака - начнем сначала.");
       System.out.println("Главного героя зовут " + GERALT_NAME);
       System.out.println(GERALT_NAME + " - ведьмак, охотник на чудовищ");
   }
}
Хулоса:
Ведьмак 4
Это уже четвертая часть Ведьмака, а Геральт из Ривии ниHow не определится, кто ему нравится больше: Йеннифэр из Венгерберга or Трисс Меригольд.
Но если вы никогда не играли в Ведьмака — начнем сначала.
Главного героя зовут Геральт из Ривии
Геральт из Ривии — ведьмак, охотник на чудовищ
Мо номи персонажхоро ба характерхои доимй чудо кардем ва акнун хатман хато нахохем кард ва хар дафъа ба дасти навиштан лозим намеояд. Боз як плюс: агар дар ниҳоят ба мо лозим ояд, ки арзиши тағирёбандаро дар тамоми барнома тағир диҳем, он кофӣ аст, ки онро дар як ҷо иҷро кунем, на он ки онро дар тамоми code дастӣ дубора иҷро кунем :)

Намудҳои тағирнопазир

Дар давоми вақти кор дар Java, шумо эҳтимол аллакай ба он одат кардаед, ки барномасоз ҳолати ҳама an objectҳоро қариб пурра назорат мекунад. Объекти дилхоҳ - офарида шудааст Cat. Агар ман мехостам, номи онро иваз кардам. Агар мехост, синну солашро дигар кард, ё чизи дигар. Аммо дар Java якчанд намуди додаҳо мавҷуданд, ки ҳолати махсус доранд. Онҳо бетағйир ё тағирнопазиранд . Ин маънои онро дорад, ки агар синф тағирнопазир бошад, ҳолати an objectҳои онро тағир додан мумкин нест. Мисолҳо? Шояд шумо ҳайрон шавед, аммо намунаи машҳури синфи Immutable ин аст String! Чунин ба назар мерасад, ки мо арзиши сатрро тағир дода наметавонем? Биёед кӯшиш кунем:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1 = "I love Python";//но поведение str1 ниHow не влияет на str2
   System.out.println(str2);//str2 продолжает указывать на строку "I love Java", хотя str1 уже указывает на другой an object
}
Хулоса: Ман Java-ро дӯст медорам Ман Java-ро дӯст медорам Баъд аз навиштани мо:
str1 = "I love Python";
an object бо сатри «Яваро дуст медорам» тагьир наёфтааст ва ба хеч кучо нарафтааст. Он бехатар мавҷуд аст ва дар дохor он ҳамон матни қаблӣ дорад. Рамз:
str1 = "I love Python";
танҳо як an objectи дигар офаридааст ва ҳоло тағирёбанда str1ба он ишора мекунад. Аммо мо ба an objectи "Ман Java-ро дӯст медорам" ба ҳеҷ ваҷҳ таъсир карда наметавонем. Хуб, биёед онро ба таври дигар санҷем! Синф Stringаз усулҳо пур аст ва баъзеи онҳо ба назар чунин менамояд, ки ҳолати сатр! Масалан, як усул вуҷуд дорад replace(). Биёед калимаи "Java" -ро дар сатри худ ба калимаи "Python" иваз кунем!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.replace("Java", "Python");//попробуем изменить состояние str1, заменив слово "Java" на “Python”
   System.out.println(str2);
}
Хулоса: Ман Java-ро дӯст медорам Ман Java-ро дӯст медорам Ин дигар кор накард! Шояд усули каҷ кор намекунад? Биёед дигареро кӯшиш кунем. Барои намуна, substring(). Сатрро дар асоси рақамҳои аломатҳои интиқолшуда бур мекунад. Биёед аломати худро ба 10 аломати аввал ҷудо кунем:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.substring(10);//обрезаем исходную строку
   System.out.println(str2);
}
Хулоса: Ман Java-ро дӯст медорам Ман Java-ро дӯст медорам Тағирнопазир дар Java: ниҳоӣ, доимӣ ва тағирнопазир - 3 Ҳеҷ чиз тағйир наёфтааст. Ва набояд дошт. Тавре ки мо гуфтем, an objectҳо Stringтағирнопазиранд. Пас ҳамаи ин усулҳои синфӣ чист String? Онҳо метавонанд хатро буранд, аломатҳои дар он бударо иваз кунанд ва ғайра. Пас, агар ҳеҷ чиз рӯй надиҳад, чаро онҳо лозиманд? Онҳо метавонанд! Аммо онҳо ҳар дафъа an objectи сатри навро бармегардонанд. Навиштан фоида надорад:
str1.replace("Java", "Python");
- шумо an objectи аслиро тағир намедиҳед. Аммо агар шумо натиҷаи усулро ба тағирёбандаи нави истинод нависед, шумо фавран фарқиятро хоҳед дид!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   String str1AfterReplacement =  str1.replace("Java", "Python");
   System.out.println(str2);

   System.out.println(str1AfterReplacement);
}
Ин ягона роҳест, ки ҳамаи ин усулҳо Stringкор мекунанд. Шумо бо an objectи "Ман Java-ро дӯст медорам" ҳеҷ кор карда наметавонед . Танҳо як an objectи нав эҷод кунед ва нависед: "Объекти нав = натиҷаи баъзе коркардҳо бо an objectи "Ман Java-ро дӯст медорам "." Кадом намудҳои дигар тағирнопазиранд? Аз он чизе, ки шумо бешубҳа бояд ҳоло дар хотир доред - ҳама синфҳои бастабандӣ бар намудҳои ибтидоӣ тағирнопазиранд. Integer, Byte, Character, Short, Boolean, Long, Double, Float- ҳамаи ин синфҳо an objectҳои тағирнашаванда эҷод мекунанд . Ин инчунин синфҳоеро дар бар мегирад, ки барои эҷоди рақамҳои калон истифода мешаванд - BigIntegerва BigDecimal. Мо ба наздикӣ аз истисноҳо гузаштем ва ба StackTrace. Ҳамин тавр: an objectҳои синфи java.lang.StackTraceElement низ тағирнопазиранд. Ин мантиқист: агар касе маълумотро дар стеки мо тағир диҳад, он метавонад тамоми корҳоро бо он рад кунад. Тасаввур кунед, ки касе ба StackTrace ворид мешавад ва OutOfMemoryError -ро ба FileNotFoundException иваз мекунад . Ва шумо бояд бо ин стек кор кунед ва сабаби хатогиро ҷустуҷӯ кунед. Ва барнома файлҳоро умуман истифода намебарад :) Аз ин рӯ, барои бехатар будан, ин an objectҳо тағирнопазир карда шуданд. Хуб, бо StackTraceElement он бештар ё камтар равшан аст. Чаро касе мехоҳад сатрҳоро тағйирнопазир гардонад? Агар имкони тағир додани арзишҳои онҳо вуҷуд дошта бошад, чӣ мушкилӣ мебуд. Эҳтимол ин боз ҳам қулайтар мебуд:/ Ин якчанд сабаб дорад. Аввалан, сарфаи хотира. Сатрҳои ивазнашавандаро ҷойгир кардан мумкин аст String Poolва ҳар дафъа ба ҷои сохтани сатрҳои нав ҳамон якҳоро истифода бурдан мумкин аст. Дуюм, бехатарӣ. Масалан, аксари логинҳо ва паролҳо дар ҳама гуна барномаҳо сатр мебошанд. Имконияти тағир додани онҳо метавонад боиси мушкилоти марбут ба иҷозат гардад. Сабабҳои дигар низ ҳастанд, аммо мо то ҳол дар омӯзиши Java ба онҳо даст наёфтаем - мо дертар бармегардем.
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION