Салам! Бүгүнкү лекцияда биз “ жеткorктүү модфикаторлор ” түшүнүгү менен таанышып , алар менен иштөөнүн мисалдарын карап чыгабыз. "Келгиле, таанышалы" деген сөз такыр туура болбой калат да: сиз алардын көбү менен мурунку лекциялардан мурунтан эле таанышсыз. Болбосо, негизги нерсе жөнүндө эс тутумубузду жаңырталы. Кирүү модификаторлору көбүнчө codeуңуздун ар кандай бөлүктөрүнө жетүү деңгээлин жөнгө салган ачкыч сөздөр. Эмне үчүн "көбүнчө"? Анткени алардын бири демейки боюнча орнотулган жана ачкыч сөз менен көрсөтүлбөйт :) Java'да бардыгы болуп төрт кирүү модификатору бар. Биз аларды эң катаалдан эң "жумшакка" чейин тизмектейбиз:
- жеке;
- корголгон;
- демейки (пакет көрүнүп турат);
- коомдук
Модификатор купуя
Private
— эң чектөөчү кирүү модификатору. Ал бир класстын ичиндеги маалыматтардын жана ыкмалардын көрүнүүсүн чектейт. Сиз бул модификаторду алуучулар жана орнотуучулар жөнүндө лекциядан билесиз. Бул мисал эсиңиздеби?
public class Cat {
public String name;
public int age;
public int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
}
Биз буга чейинки макалалардын биринде карадык. Бул жерде биз олуттуу ката кетирдик: биз маалыматтарыбызды ачтык, анын натыйжасында башка программисттер класс талааларына түздөн-түз кирүү мүмкүнчүлүгүнө ээ болуп, алардын баалуулуктарын өзгөртүштү. Мындан тышкары, бул баалуулуктар текшерүүсүз дайындалган, анын натыйжасында биздин программада жашы -1000 жыл, аты "" жана салмагы 0 болгон мышык түзсө болот. Бул маселени чечүү үчүн, биз колдонулган алгычтар жана орнотуучулар , ошондой эле модификатордун жардамы менен берorштерге жетүү чектелген private
.
public class Cat {
private String name;
private int age;
private int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
public String getName() {
return name;
}
public void setName(String name) {
// checking the input parameter
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
// checking the input parameter
this.age = age;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
// checking the input parameter
this.weight = weight;
}
}
Чындыгында, талааларга кирүү мүмкүнчүлүгүн чектөө жана Getters-Setter-ди ишке ашыруу private
реалдуу жумушта колдонуунун эң кеңири таралган мисалы болуп саналат. Башкача айтканда, программада инкапсуляцияны ишке ашыруу бул модификатордун негизги максаты болуп саналат. Бул, демек, талааларга гана тиешелүү эмес. Сиздин программаңызда өтө татаал функцияларды ишке ашырган ыкма бар экенин элестетиңиз. Муну мисал катары келтириш үчүн... Сиздин методуңуз readDataFromCollider()
киргизүү катары маалыматтары бар даректи алып, Чоң Адрон Коллайдеринен маалыматтарды byte форматында окуп, бул маалыматтарды текстке айлантып, файлга жазып, басып чыгарат дейли. Кодду айтпай эле коелу, методдун сүрөттөлүшү да үрөй учурарлык көрүнөт :) Коддун окулушун жогорулатуу үчүн методдун татаал логикасын бир жерге жазбай, тескерисинче, функционалдуулукту бузуп койсоңуз жакшы болмок. өзүнчө ыкмаларга. Мисалы, метод readByteData()
маалыматтарды окуу, convertBytesToSymbols()
коллайдерден окулган маалыматтарды текстке айландыруу, saveToFile()
алынган текстти файлга сактоо жана printColliderData()
биздин маалымат файлыбызды басып чыгаруу үчүн жооп берет. Бул ыкма readDataFromCollider()
кыйла жөнөкөй болуп калат:
public class ColliderUtil {
public void readDataFromCollider(Path pathToData) {
byte[] colliderData = readByteData(pathToData);
String[] textData = convertBytesToSymbols(colliderData);
File fileWithData = saveToFile(textData);
printColliderData(fileWithData);
}
public byte[] readByteData(Path pathToData) {
// reads data in bytes
}
public String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
// convert bytes to characters
}
public File saveToFile(String[] colliderData) {
// save the read data to a file
}
public void printColliderData(File fileWithColliderData) {
// print data from file
}
}
Бирок, интерфейстер боюнча лекциядан эстегендей, колдонуучу акыркы интерфейске гана кире алат. Ал эми биздин 4 методубуз ага кирбейт. Алар жардамчы болуп саналат : биз аларды codeдун окууга жөндөмдүүлүгүн жакшыртуу жана төрт түрдүү тапшырманы бир ыкмага тыгып калбоо үчүн түздүк. Колдонуучуга бул ыкмаларга мүмкүнчүлүк берүүнүн кереги жок. Коллайдер менен иштөөдө колдонуучу бул ыкмага жетүү мүмкүнчүлүгүнө ээ болсо convertBytesToSymbols()
, ал бул ыкма эмне экенин жана эмне үчүн керек экенин түшүнбөй калышы мүмкүн. Кандай byteтар айландырылат? Алар кайдан келген? Эмне үчүн аларды текстке айландыруу? Бул ыкмада иштеген логика колдонуучунун интерфейсинин бир бөлүгү эмес. Метод гана readDataFromCollider()
интерфейстин бир бөлүгү болуп саналат. Бул төрт "ички" ыкмалар менен эмне кылуу керек? Туура! Модификатор менен аларга кирүү мүмкүнчүлүгүн чектеңиз private
. Ушундай жол менен алар класстын ичинде өз ишин оңой аткарып, ар биринин логикасына өзүнчө муктаж болбогон колдонуучуну чаташтырбай алышат.
public class ColliderUtil {
public void readDataFromCollider(Path pathToData) {
byte[] colliderData = readByteData(pathToData);
String[] textData = convertBytesToSymbols(colliderData);
File fileWithData = saveToFile(textData);
printColliderData(fileWithData);
}
private byte[] readByteData(Path pathToData) {
// reads data in bytes
}
private String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
// convert bytes to characters
}
private File saveToFile(String[] colliderData) {
// save the read data to a file
}
private void printColliderData(File fileWithColliderData) {
// print data from file
}
}
Модификатор корголгон
Кийинки эң чектөөчү кирүү өзгөрткүчү болуп саналатprotected
. Кирүү модификатору менен белгиленген талаалар жана ыкмалар protected
көрүнөт:
- биздики менен бир пакетте турган бардык класстардын ичинде;
- биздин класстын бардык улантуучу класстарынын ичинде.
protected
колдонуунун учурлары - га караганда азыраак private
жана алар конкреттүү. Элестеткиле, бизде AbstractSecretAgent
кандайдыр бир чалгындоо кызматынын жашыруун агентин билдирген абстракттуу класс, ошондой эле top_secret
бул классты жана анын тукумдарын камтыган пакет бар. Андан конкреттүү класстар - FBISecretAgent
, MI6SecretAgent
, MossadSecretAgent
ж.б. Абстрактуу класстын ичинде биз агент эсептегичти ишке киргизгибиз келет. Программанын бир жеринде жаңы агент an objectи түзүлгөндө, ал көбөйөт.
package top_secret;
public abstract class AbstractSecretAgent {
public static int agentCount = 0;
}
Бирок биздин агенттер жашыруун! Бул алардын саны жөнүндө алар гана жана башка эч ким билбеши керек дегенди билдирет. protected
Биз талаага модификаторду оңой эле кошо алабыз agentCount
, андан кийин башка жашыруун агент класстарынын an objectтери же биздин "жашыруун" пакетибизде жайгашкан класстар анын маанисин ала алышат top_secret
.
public abstract class AbstractSecretAgent {
protected static int agentCount = 0;
}
Мына ушундай конкреттүү тапшырмалар үчүн модификатор керек protected
:)
пакеттин көрүнүүчү өзгөрткүчү
Кийинки биздин тизмеде модификаторdefault
же, ал ошондой эле деп аталат package visible
. Ал ачкыч сөз менен көрсөтүлбөйт, анткени ал Java-да бардык талаалар жана ыкмалар үчүн демейки боюнча коюлган. Эгер сиз codeуңузга жазсаңыз -
int x = 10;
... өзгөрмө x
ушул эле мүмкүнчүлүккө ээ болот package visible
. Эгерде метод (же өзгөрмө) кандайдыр бир модификатор менен белгиленбесе, ал "демейки модификатор" менен белгиленген деп эсептелет. Мындай модификатору бар өзгөрмөлөр же методдор (б.а. такыр жок) алар жарыяланган пакеттин бардык класстарына көрүнүп турат. Жана аларга гана. Анын колдонулушу өзгөргүч сыяктуу эле чектелген protected
. Көбүнчө, default
-access пакетте колдонулат, анда кээ бир пайдалуу класстар бар, алар бул пакеттеги бардык башка класстардын функцияларын ишке ашырbyte. Мисал келтирели. Элестеткиле, бизде " кызмат " пакети бар. Анын ичинде маалымат базасы менен иштеген ар кандай класстар бар. Мисалы, UserService
маалымат базасынан колдонуучунун маалыматтарын окуй турган класс, CarService
ошол эле маалымат базасынан унаалар жөнүндө маалыматтарды окуй турган класс жана башка класстар бар, алардын ар бири өзүнүн типтеги an objectтери менен иштеп, алар жөнүндө маалыматтарды маалымат базасынан окуйт.
package services;
public class UserService {
}
package services;
public class CarService {
}
Бирок, маалымат базасындагы маалыматтар бир форматта болгондо, жагдай оңой болушу мүмкүн, бирок бизге башка форматта керек. Колдонуучунун туулган күнү маалымат базасында TIMESTAMP WITH TIME ZONE форматында сакталганын элестетиңиз...
2014-04-04 20:32:59.390583+02
...анын ордуна бизге эң жөнөкөй an object керек - java.util.Date
. services
Бул үчүн, пакеттин ичинде атайын класс түзө алабыз Mapper
. Ал маалымат базасынан маалыматтарды биз жакшы билген Java an objectилерине айландыруу үчүн жооптуу болот. Жөнөкөй жардамчы класс. Биз, адатта, бардык класстарды катары түзөбүз public class ClassName
, бирок бул зарыл эмес. Биз жардамчы классыбызды жөн эле деп жарыялай алабыз class Mapper
. Бул учурда, ал дагы эле өз ишин аткарат, бирок пакеттен тышкары эч кимге көрүнбөйт services
!
package services;
class Mapper {
}
package services;
public class CarService {
Mapper mapper;
}
Жана бул, чындыгында, туура логика: эмне үчүн пакеттен тышкаркы бирөө бир эле пакеттин класстары менен гана иштеген жардамчы классты көрөт?
коомдук өзгөрткүч
Ал эми тизмеде акыркы, бирок жок дегенде - өзгөртүүчүpublic
! Сиз аны JavaRush программасында окуунун биринчи күнүндө тааныштыңыз public static void main(String[] args)
. Эми сиз интерфейстер жөнүндө лекцияларды окуп чыккандан кийин, анын максаты сизге түшүнүктүү :) Анткени, public
ал колдонуучуларга бир нерсе берүү үчүн түзүлгөн. Мисалы, программаңыздын интерфейси. Сиз котормочу программасын жаздыңыз дейли, ал орусча текстти англис тorне которо алат. translate(String textInRussian)
Сиз керектүү логика ишке ашырылган ыкманы түздүңүз . Сиз бул ыкманы сөз менен белгилегенсиз public
, эми ал интерфейстин бир бөлүгү болуп калат:
public class Translator {
public String translate(String textInRussian) {
// translates text from Russian to English
}
}
Сиз бул ыкмага чакырууну программанын экранындагы "которуу" баскычы менен байланыштырсаңыз болот - ушуну менен! Аны каалаган адам колдоно алат. Модификатор менен белгиленген codeдун бөлүктөрү public
акыркы колдонуучуга арналган. Турмуштан бир мисал келтире турган болсок, private
мунун баары телевизор иштеп жатканда анын ичинде болуп жаткан процесстер жана public
бул телевизордун пультундагы баскычтар, аны колдонуучу аны башкара алат. Ошол эле учурда ал телевизор кандай иштеп жатканын жана анын кандай иштеп жатканын билүүгө муктаж эмес. Пульт - public
методдордун жыйындысы: on()
, off()
, nextChannel()
, previousChannel()
, increaseVolume()
, decreaseVolume()
ж.б.
GO TO FULL VERSION