हाय! आजच्या धड्यात, आम्ही ऍक्सेस मॉडिफायर्सच्या संकल्पनेशी परिचित होऊ आणि त्यांच्यासह कसे कार्य करावे याचे उदाहरण विचारात घेऊ. अर्थात, 'परिचित व्हा' असे म्हणणे अगदी बरोबर नाही: मागील धड्यांमधून तुम्ही त्यांच्यापैकी बहुतेकांशी आधीच परिचित आहात. फक्त बाबतीत, सर्वात महत्वाच्या मुद्द्याबद्दलची आठवण ताजी करूया. मॉडिफायर्स ऍक्सेस हे बहुधा कीवर्ड असतात जे तुमच्या कोडच्या वेगवेगळ्या भागांमध्ये ऍक्सेसचे नियमन करतात. 'बहुतेकदा' का? कारण त्यातील एक कीवर्ड न वापरता डिफॉल्टनुसार सेट केला आहे :) Java मध्ये चार ऍक्सेस मॉडिफायर आहेत. आम्ही त्यांना सर्वात प्रतिबंधित ते सर्वात 'नम्र' क्रमाने सूचीबद्ध करतो:
- खाजगी
- डीफॉल्ट (पॅकेज दृश्यमान);
- संरक्षित;
- सार्वजनिक
खाजगी सुधारक
खाजगी हा सर्वात प्रतिबंधित प्रवेश सुधारक आहे. हे डेटा आणि पद्धतींची दृश्यमानता एका वर्गात मर्यादित करते. गेटर्स आणि सेटर बद्दलच्या धड्यातून तुम्हाला हा सुधारक माहित आहे. हे उदाहरण आठवते?
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 आहे. या समस्येचे निराकरण करण्यासाठी, आम्ही गेटर्स आणि सेटर्सचा वापर केला आणि डेटावर प्रवेश मर्यादित करण्यासाठी खाजगी सुधारक देखील वापरले.
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) {
// input parameter check
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
// input parameter check
this.age = age;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
// input parameter check
this.weight = weight;
}
}
मूलभूतपणे, फील्डमध्ये प्रवेश मर्यादित करणे आणि गेटर्स आणि सेटरची अंमलबजावणी करणे ही खाजगी किती सामान्य उदाहरणे आहेतप्रत्यक्ष कामात वापरला जाईल. दुसऱ्या शब्दांत, या सुधारकाचा मुख्य उद्देश प्रोग्राममध्ये एन्कॅप्सुलेशन साध्य करणे हा आहे. हे फक्त फील्डवर लागू होत नाही, तसे. कल्पना करा की तुमच्या प्रोग्राममध्ये एक पद्धत आहे जी काही अतिशय जटिल कार्यक्षमता लागू करते. उदाहरण म्हणून आपण काय सुचवू शकतो? समजा तुमची readDataFromCollider() पद्धत डेटा अॅड्रेस इनपुट म्हणून स्वीकारते, लार्ज हॅड्रॉन कोलायडरचा डेटा बाइट फॉरमॅटमध्ये वाचते, हा डेटा टेक्स्टमध्ये रूपांतरित करते, फाईलमध्ये लिहते आणि प्रिंट करते. पद्धतीचे वर्णन देखील भयानक दिसते, कोडबद्दल काहीही सांगायचे नाही :) कोड अधिक वाचनीय होण्यासाठी, सर्व पद्धतीचे जटिल तर्क एकाच ठिकाणी न लिहिणे चांगले होईल. त्याऐवजी, आपण कार्यक्षमतेला वेगळ्या पद्धतींमध्ये विभाजित केले पाहिजे. उदाहरणार्थ, 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) {
// Converts bytes to characters
}
public File saveToFile(String[] colliderData) {
// Saves read data to a file
}
public void printColliderData(File fileWithColliderData) {
// Prints data from the file
}
}
तथापि, इंटरफेसबद्दलच्या धड्यावरून तुम्हाला आठवत असेल, वापरकर्त्याला फक्त बाह्य इंटरफेसमध्ये प्रवेश मिळतो. आणि आमच्या 4 पद्धतींचा भाग नाही. त्या सहाय्यक पद्धती आहेत: आम्ही कोडची वाचनीयता सुधारण्यासाठी आणि एका पद्धतीमध्ये चार भिन्न कार्ये क्रॅम न करण्यासाठी त्या तयार केल्या आहेत. तुम्हाला वापरकर्त्याला या पद्धतींमध्ये प्रवेश देण्याची आवश्यकता नाही. कोलायडरसोबत काम करताना वापरकर्त्यांना कन्व्हर्टबाइट्सटोसिम्बॉल्स() पद्धतीमध्ये प्रवेश असल्यास , ते बहुधा या पद्धतीमुळे गोंधळून जातील आणि ते कशासाठी आहे याबद्दल आश्चर्यचकित होतील. कोणते बाइट्स रूपांतरित केले जातात? ते कुठून आले? त्यांना मजकूरात का रूपांतरित करायचे? या पद्धतीमध्ये अंमलात आणलेले लॉजिक हे वापरकर्त्याच्या समोर येणाऱ्या इंटरफेसचा भाग नाही. फक्त readDataFromCollider()पद्धत इंटरफेसचा भाग आहे. मग या चार 'अंतर्गत' पद्धतींचे आपण काय करायचे? बरोबर! त्यांना प्रवेश मर्यादित करण्यासाठी खाजगी सुधारक वापरा . असे केल्याने ते वापरकर्त्याला गोंधळात टाकल्याशिवाय वर्गात त्यांचे कार्य शांततेने करू देतात, ज्यांना प्रत्येक वैयक्तिक पद्धतीचे तर्क माहित असणे आवश्यक नसते.
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) {
// Converts bytes to characters
}
private File saveToFile(String[] colliderData) {
// Saves read data to a file
}
private void printColliderData(File fileWithColliderData) {
// Prints data from the file
}
}
संरक्षित सुधारक
पुढील सर्वात प्रतिबंधात्मक सुधारक संरक्षित आहे . संरक्षित प्रवेश सुधारकाने चिन्हांकित केलेली फील्ड आणि पद्धती दृश्यमान असतील:- आमच्या सारख्याच पॅकेजमध्ये समाविष्ट असलेल्या सर्व वर्गांमध्ये;
- आमच्या वर्गाचा वारसा मिळालेल्या सर्व वर्गांमध्ये.
public abstract class AbstractSecretAgent {
public static int agentCount = 0;
}
पण आमचे एजंट गुप्त आहेत! याचा अर्थ त्यांच्यापैकी किती अस्तित्वात आहेत हे त्यांना आणि इतर कोणालाही कळू नये. आम्ही agent_counter फील्डमध्ये संरक्षित सुधारक सहजपणे जोडू शकतो . मग आमच्या top_secret पॅकेजमध्ये असलेल्या इतर गुप्त एजंट वर्ग आणि इतर वर्गांची उदाहरणे त्याचे मूल्य मिळवू शकतात.
public abstract class AbstractSecretAgent {
protected static int agent_counter = 0;
}
आणि हे असे विशेष कार्य आहे ज्यासाठी संरक्षित सुधारक आवश्यक आहे :)
पॅकेज दृश्यमान सुधारक
सूचीच्या पुढे डीफॉल्ट सुधारक आहे, ज्याला पॅकेज दृश्यमान सुधारक म्हणून देखील ओळखले जाते. हे कीवर्डद्वारे सूचित केले जात नाही, कारण Java हे सर्व फील्ड आणि पद्धतींवर डीफॉल्टनुसार लागू करते. तुम्ही तुमच्या कोडमध्ये खालील लिहिल्यास:
int x = 10
x व्हेरिएबलमध्ये हे पॅकेज दृश्यमान प्रवेश असेल . ते काय करते हे लक्षात ठेवणे सोपे आहे. मूलभूतपणे, डीफॉल्ट = संरक्षित वारसा :) संरक्षित सुधारकाप्रमाणे, त्याचा अनुप्रयोग मर्यादित आहे. बर्याचदा, डिफॉल्ट ऍक्सेस पॅकेजमध्ये वापरला जातो ज्यामध्ये काही उपयुक्तता वर्ग असतात जे पॅकेजमधील इतर सर्व वर्गांच्या कार्यक्षमतेची अंमलबजावणी करत नाहीत. एक उदाहरण देऊ. कल्पना करा की आमच्याकडे 'सेवा' पॅकेज आहे. यात डेटाबेससह कार्य करणारे विविध वर्ग आहेत. उदाहरणार्थ, एक UserService वर्ग आहे जो डेटाबेसमधील वापरकर्ता डेटा वाचतो, एक CarServiceवर्ग जो समान डेटाबेसमधील कार डेटा वाचतो आणि इतर वर्ग, ज्यापैकी प्रत्येक विशिष्ट प्रकारच्या ऑब्जेक्टसह कार्य करतो आणि डेटाबेसमधील संबंधित डेटा वाचतो.
package services;
public class UserService {
}
package services;
public class CarService {
}
परंतु डेटाबेसमधील डेटा एका फॉरमॅटमध्ये असणे सोपे आहे आणि आम्हाला ते दुसर्या स्वरूपात आवश्यक आहे. कल्पना करा की डेटाबेसमध्ये वापरकर्त्यांच्या जन्मतारखा <TIMESTAMP WITH TIME ZONE> म्हणून संग्रहित केल्या आहेत...
2014-04-04 20:32:59.390583+02
...आणि त्याऐवजी आपल्याला सर्वात सोपी वस्तू हवी आहे - java.util.Date . या समस्येचे निराकरण करण्यासाठी, सेवा पॅकेजमध्ये, आम्ही एक विशेष मॅपर वर्ग तयार करू शकतो. डेटाबेसमधील डेटा आमच्या परिचित Java ऑब्जेक्ट्समध्ये रूपांतरित करण्यासाठी ते जबाबदार असेल. एक साधा मदतनीस वर्ग. आम्ही सहसा सर्व वर्गांना सार्वजनिक वर्ग ClassName म्हणून घोषित करतो , परंतु ही आवश्यकता नाही. आम्ही आमचा मदतनीस वर्ग फक्त क्लास मॅपर म्हणून घोषित करू शकतो . या प्रकरणात, ते अद्याप त्याचे कार्य करते, परंतु सेवा पॅकेजच्या बाहेरील कोणालाही ते दृश्यमान नाही !
package services;
class Mapper {
}
package services;
public class CarService {
Mapper mapper;
}
आणि येथे मूलभूत तर्क आहे: पॅकेजच्या बाहेरील कोणालाही केवळ त्या पॅकेजमधील वर्गांसह कार्य करणारा मदतनीस वर्ग का पाहण्याची आवश्यकता आहे?
सार्वजनिक सुधारक
आणि शेवटचे परंतु किमान नाही, सार्वजनिक सुधारक! तुम्ही या सुधारकाला तुमच्या CodeGym वर अभ्यासाच्या पहिल्या दिवशी भेटलात जेव्हा तुम्ही पब्लिक स्टॅटिक व्हॉइड main(String[] args) पहिल्यांदा चालवला होता . आता तुम्ही इंटरफेसच्या धड्याचा अभ्यास केला आहे, त्याचा उद्देश तुमच्यासाठी स्पष्ट आहे :) शेवटी, सार्वजनिक सुधारक वापरकर्त्यांना काहीतरी देण्यासाठी तयार केले गेले. उदाहरणार्थ, तुमच्या प्रोग्रामचा इंटरफेस. समजा तुम्ही एक अनुवादक प्रोग्राम लिहिला आहे जो रशियन मजकूर इंग्रजीमध्ये अनुवादित करू शकतो. तुम्ही भाषांतर (स्ट्रिंग टेक्स्टइन रशियन) पद्धत तयार केली आहे जी सर्व आवश्यक तर्क लागू करते. तुम्ही ही पद्धत पब्लिक या शब्दाने चिन्हांकित केली आहे आणि आता ती इंटरफेसचा भाग आहे:
public class Translator {
public String translate(String textInRussian) {
// Translates text from Russian to English
}
}
तुम्ही ही पद्धत स्क्रीनवरील 'अनुवाद' बटणावर बांधू शकता आणि तुम्ही पूर्ण केले! ते कोणीही वापरू शकतो. पब्लिक मॉडिफायरसह चिन्हांकित केलेले कोडचे भाग अंतिम वापरकर्त्यासाठी आहेत. वास्तविक जीवनातील उदाहरण देताना, खाजगी टीव्हीमध्ये होणाऱ्या सर्व प्रक्रियांसाठी आहे, परंतु टीव्ही व्यवस्थापित करण्यासाठी वापरल्या जाणार्या रिमोट कंट्रोलवरील बटणांसाठी सार्वजनिक आहे. इतकेच काय, वापरकर्त्याला टेलिव्हिजन कसा बांधला जातो किंवा तो कसा काम करतो हे जाणून घेण्याची गरज नाही. रिमोट कंट्रोल हा सार्वजनिक पद्धतींचा संच आहे: चालू() , बंद () , नेक्स्ट चॅनेल () , मागील चॅनेल () , वाढवावॉल्युम () , घटवता () इ. तुम्ही जे शिकलात ते बळकट करण्यासाठी, आम्ही तुम्हाला आमच्या Java कोर्समधील व्हिडिओ धडा पाहण्याचा सल्ला देतो
GO TO FULL VERSION