हाय! तुम्ही "सुधारकर्ता" या शब्दाशी आधीच परिचित आहात. कमीतकमी, तुम्हाला ऍक्सेस मॉडिफायर (सार्वजनिक, खाजगी) आणि स्टॅटिक मॉडिफायरचा सामना करावा लागला आहे. आज आपण फायनल नावाच्या एका विशेष मॉडिफायरवर चर्चा करू . आपण आमच्या प्रोग्रामचे अंतिम सुधारक "सिमेंट्स" भाग म्हणू शकता जिथे स्थिर, अस्पष्ट, न बदलणारे वर्तन आवश्यक आहे. तुमच्या प्रोग्राममध्ये तीन ठिकाणे आहेत जी तुम्ही वापरू शकता: वर्ग, पद्धती आणि चल.
चला त्या क्रमाने चालवूया. जर अंतिम सुधारक क्लास डिक्लेरेशनमध्ये वापरला असेल, तर याचा अर्थ क्लास इनहेरिट केला जाऊ शकत नाही. मागील धड्यांमध्ये, आम्ही एक साधे वारसा उदाहरण वापरले: आमच्याकडे
काहीही बदलले नाही. आणि ते नसावे. आम्ही आधी म्हटल्याप्रमाणे, स्ट्रिंग्स अपरिवर्तनीय आहेत. तर, वर्गातील सर्व पद्धतींचे काय
![Java मधील निश्चित मूल्ये: अंतिम, स्थिरांक आणि अपरिवर्तनीय - 2](https://cdn.codegym.cc/images/article/6c57a5a9-d609-454a-819e-22a811604d42/800.jpeg)
Animal
पालक वर्ग आणि दोन मुलांचे वर्ग होते: Cat
आणिDog
public class Animal {
}
public class Cat extends Animal {
// Fields and methods of the Cat class
}
public class Dog extends Animal {
// Fields and methods of the Dog class
}
तथापि, जर आपण वर्गावर अंतिमAnimal
सुधारक वापरला तर , Cat
आणि Dog
वर्ग ते इनहेरिट करू शकत नाहीत.
public final class Animal {
}
public class Cat extends Animal {
// Error! Cannot inherit from final Animal
}
कंपाइलर लगेच एरर जनरेट करतो. Java मध्ये, अनेक अंतिम वर्ग आधीच लागू केले आहेत. आपण वारंवार वापरत असलेल्यांपैकी, String
सर्वात सुप्रसिद्ध आहे. शिवाय, जर एखादा वर्ग अंतिम म्हणून घोषित केला गेला तर वर्गाच्या सर्व पद्धती देखील अंतिम होतात . याचा अर्थ काय? अंतिम सुधारक वापरून पद्धत घोषित केली असल्यास , तुम्ही ती पद्धत ओव्हरराइड करू शकत नाही. उदाहरणार्थ, येथे आपल्याकडे एक Animal
वर्ग आहे जो एक speak()
पद्धत घोषित करतो. परंतु, कुत्रे आणि मांजरी निश्चितपणे वेगवेगळ्या प्रकारे "बोलतात". Cat
म्हणून, आम्ही स्पीक() पद्धती आणि क्लास या दोन्हीमध्ये घोषित करू Dog
, परंतु आम्ही त्या वेगळ्या पद्धतीने लागू करू.
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void speak() {
System.out.println("Woof!");
}
}
आम्ही Cat
आणि Dog
वर्गांना मूळ वर्गात घोषित केलेली पद्धत ओव्हरराइड केली आहे. आता, प्राणी कोणत्या प्रकारची वस्तू आहे यावर अवलंबून, वेगळ्या पद्धतीने बोलेल:
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
cat.speak();
dog.speak();
}
}
आउटपुट: म्याऊ! वूफ! तथापि, जर आम्ही Animal
वर्गाची speak()
पद्धत अंतिम म्हणून घोषित केली, तर आम्ही ती इतर वर्गांमध्ये ओव्हरराइड करू शकत नाही:
public class Animal {
public final void speak() {
System.out.println("Hello!");
}
}
public class Cat extends Animal {
@Override
public void speak() {// Error! A final method can't be overridden!
System.out.println("Meow!");
}
}
speak()
आणि आमच्या ऑब्जेक्ट्सना पॅरेंट क्लासमध्ये परिभाषित केल्यानुसार पद्धत वापरण्यास भाग पाडले जाईल :
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
cat.speak();
dog.speak();
}
आउटपुट: हॅलो! नमस्कार! आता, अंतिम व्हेरिएबल्सबद्दल. त्यांना स्थिरांक म्हणूनही ओळखले जाते . प्रथम (आणि सर्वात महत्त्वाचे म्हणजे), स्थिर मूल्यास नियुक्त केलेले प्रारंभिक मूल्य बदलले जाऊ शकत नाही. हे एकदा आणि सर्वांसाठी नियुक्त केले आहे.
public class Main {
private static final int CONSTANT_EXAMPLE = 333;
public static void main(String[] args) {
CONSTANT_EXAMPLE = 999;// Error! You can't assign a new value to a final variable!
}
}
स्थिरांक ताबडतोब सुरू करणे आवश्यक नाही. ते नंतर करता येईल. परंतु, सुरुवातीला नियुक्त केलेले मूल्य कायमचे समान राहील.
public static void main(String[] args) {
final int CONSTANT_EXAMPLE;
CONSTANT_EXAMPLE = 999;// This is allowed
}
दुसरे, आमच्या व्हेरिएबलचे नाव लक्षात घ्या. जावामध्ये स्थिरांकांसाठी वेगळे नामकरण आहे. हे नेहमीचे कॅमलकेस नोटेशन नाही . जर ते सामान्य व्हेरिएबल असते, तर आम्ही त्याला स्थिर उदाहरण म्हटले असते. परंतु, स्थिरांकांची नावे शब्दांमधील अंडरस्कोरसह (एकापेक्षा जास्त शब्द असल्यास), उदा. "CONSTANT_EXAMPLE". आम्हाला स्थिरांकांची गरज का आहे? उदाहरणार्थ, तुम्ही प्रोग्राममध्ये नियमितपणे वापरत असलेले निश्चित मूल्य असल्यास ते खूप उपयुक्त आहेत. उदाहरणार्थ, तुम्ही इतिहास घडवण्याचा आणि "द विचर 4" हा गेम स्वतः लिहिण्याचा निर्णय घेतला आहे. गेम स्पष्टपणे नायकाचे नाव वापरेल: "जेराल्ट ऑफ रिव्हिया". ही स्ट्रिंग (आणि इतर नायकांची नावे) एक स्थिर म्हणून घोषित केली गेली आहे: त्याचे मूल्य एकाच ठिकाणी संग्रहित केले जाईल आणि ते दशलक्ष वेळा प्रविष्ट करताना आपण निश्चितपणे टायपो करणार नाही.
public class TheWitcher4 {
private static final String GERALT_NAME = "Geralt of Rivia";
private static final String YENNEFER_NAME = "Yennefer of Wengerberg";
private static final String TRISS_NAME = "Triss Merigold";
public static void main(String[] args) {
System.out.println("The Witcher 4");
System.out.println("It's already the fourth Witcher game, but " + GERALT_NAME + " still can't decide who" +
" he likes more: " + YENNEFER_NAME + " or " + TRISS_NAME);
System.out.println("But, if you've never played The Witcher before, we'll start from the beginning.");
System.out.println("The protagonist's name is " + GERALT_NAME);
System.out.println(GERALT_NAME + " is a witcher, a monster hunter");
}
}
आउटपुट: द विचर 4 हा आधीपासूनच चौथा विचर गेम आहे, परंतु रिव्हियाचा गेराल्ट अद्याप ठरवू शकत नाही की त्याला कोण अधिक आवडते: वेंगरबर्गचे येनेफर किंवा ट्रिस मेरिगोल्ड परंतु, जर तुम्ही याआधी कधीही विचर खेळला नसेल, तर आम्ही या खेळापासून सुरुवात करू. सुरुवात नायकाचे नाव रिव्हियाचे गेराल्ट आहे रिव्हियाचा गेराल्ट एक जादूगार आहे, एक राक्षस शिकारी आहे आम्ही नायकांची नावे स्थिरांक म्हणून घोषित केली आहेत. आता आम्ही निश्चितपणे टायपो करणार नाही आणि प्रत्येक वेळी त्यांना हाताने लिहिण्याची गरज नाही. आणखी एक फायदा: आम्हाला संपूर्ण प्रोग्राममध्ये व्हेरिएबलचे मूल्य बदलण्याची आवश्यकता असल्यास, तुम्ही संपूर्ण कोड बेसवर व्यक्तिचलितपणे बदल करण्याऐवजी ते एकाच ठिकाणी करू शकता. :)
अपरिवर्तनीय प्रकार
तुम्ही Java सह काम केल्यामुळे, तुम्हाला कदाचित या कल्पनेची सवय झाली असेल की सर्व वस्तूंच्या स्थितीवर प्रोग्रामरचे जवळजवळ पूर्ण नियंत्रण असते. जर तुम्हाला एखादी वस्तू तयार करायची असेलCat
तर तुम्ही करू शकता. आपण त्याचे नाव बदलू इच्छित असल्यास, आपण करू शकता. जर तुम्हाला त्याचे वय किंवा दुसरे काही बदलायचे असेल तर तुम्ही करू शकता. परंतु Java मध्ये अनेक डेटा प्रकार आहेत ज्यात विशेष गुणधर्म आहेत. ते अपरिवर्तनीय आहेत . जर वर्ग अपरिवर्तनीय असेल, तर त्याच्या वस्तूंची स्थिती बदलली जाऊ शकत नाही. काही उदाहरणे हवी आहेत? हे तुम्हाला आश्चर्यचकित करेल, परंतु सर्वात सुप्रसिद्ध अपरिवर्तनीय वर्ग म्हणजे स्ट्रिंग! तर, आम्ही खरोखर स्ट्रिंगचे मूल्य बदलू शकत नाही? बरं, चला प्रयत्न करूया:
public static void main(String[] args) {
String str1 = "I love Java";
String str2 = str1;// Both reference variables point to the same string.
System.out.println(str2);
str1 = "I love Python";// but changing str1 has no impact on str2
System.out.println(str2);// str2 continues to point to the "I love Java" string, but str1 now points to a different object
}
आउटपुट: मला जावा आवडते मला जावा आवडते आम्ही लिहिल्यानंतर
str1 = "I love Python";
स्ट्रिंग "I love Java"
ऑब्जेक्ट बदलला नाही किंवा कुठेही गेला नाही. तो अजूनही आनंदाने अस्तित्वात आहे आणि पूर्वीसारखाच मजकूर आहे. कोड
str1 = "I love Python";
फक्त दुसरा ऑब्जेक्ट तयार केला, जो str1 आता दर्शवितो. परंतु, "मला जावा आवडते" स्ट्रिंग ऑब्जेक्टवर कोणताही परिणाम झालेला दिसत नाही. ठीक आहे, चला काहीतरी वेगळे करून पहा! वर्ग String
पद्धतींनी भरलेला आहे, आणि त्यापैकी काही ऑब्जेक्टची स्थिती बदलताना दिसतात! उदाहरणार्थ, एक replace()
पद्धत आहे. चला आपल्या स्ट्रिंगमधील "जावा" शब्द "पायथन" मध्ये बदलूया!
public static void main(String[] args) {
String str1 = "I love Java";
String str2 = str1;// Both reference variables point to the same string.
System.out.println(str2);
str1.replace("Java", "Python");// We try to change the state of str1 by swapping the word "Java" with "Python"
System.out.println(str2);
}
आउटपुट: मला जावा आवडते मला जावा आवडते ते पुन्हा कार्य करत नाही! कदाचित बदलण्याची पद्धत कार्य करत नाही? चला काहीतरी वेगळं करून बघूया. उदाहरणार्थ, substring()
. हे वितर्क म्हणून पास केलेल्या वर्ण निर्देशांकांवर आधारित सबस्ट्रिंग मिळवते. चला आमच्या स्ट्रिंगचे पहिले 10 वर्ण कापून टाका:
public static void main(String[] args) {
String str1 = "I love Java";
String str2 = str1;// Both reference variables point to the same string.
System.out.println(str2);
str1.substring(10);// Truncate the original String
System.out.println(str2);
}
आउटपुट: मला जावा आवडते मला जावा आवडते ![Java मधील निश्चित मूल्ये: अंतिम, स्थिरांक आणि अपरिवर्तनीय - 3](https://cdn.codegym.cc/images/article/76f63ce7-29a3-4141-94c5-c4320c93f21d/800.jpeg)
String
? शेवटी, ते स्ट्रिंग कापून टाकू शकतात, वर्ण बदलू शकतात आणि बरेच काही करू शकतात. काहीच झाले नाही तर काय हरकत आहे? ते प्रत्यक्षात या गोष्टी करू शकतात! परंतु, ते प्रत्येक वेळी नवीन स्ट्रिंग परत करतात. लिहिण्यात अर्थ नाही
str1.replace("Java", "Python");
कारण तुम्ही मूळ ऑब्जेक्ट बदलू शकत नाही. परंतु, जर तुम्ही पद्धतीचा परिणाम नवीन संदर्भ चलवर लिहिला, तर तुम्हाला फरक लगेच दिसेल!
public static void main(String[] args) {
String str1 = "I love Java";
String str2 = str1;// Both reference variables point to the same string.
System.out.println(str2);
String str1AfterReplacement = str1.replace("Java", "Python");
System.out.println(str2);
System.out.println(str1AfterReplacement);
}
सर्व String
पद्धती अशा प्रकारे कार्य करतात. वस्तूला काहीही करता येत नाही "I love Java"
. तुम्ही फक्त एक नवीन ऑब्जेक्ट तयार करू शकता आणि लिहू शकता: "<new object> = हाताळणीचा परिणाम "I love Java" object "
. इतर कोणते प्रकार अपरिवर्तनीय आहेत? तुम्हाला निश्चितपणे लक्षात ठेवणे आवश्यक आहे की काही आदिम प्रकारांसाठी सर्व रॅपर वर्ग आहेत. Integer
, Byte
, Character
, Short
, Boolean
, Long
, Double
, Float
: हे सर्व वर्ग immutable
ऑब्जेक्ट्स तयार करतात (आम्ही त्यांच्याबद्दल आगामी धड्यांमध्ये बोलू). यामध्ये मोठ्या संख्येने तयार करण्यासाठी वापरल्या जाणार्या वर्गांचा समावेश आहे, जसे की BigInteger
आणि BigDecimal
. आम्ही नुकतेच अपवाद समाविष्ट केले आहेत आणि स्टॅक ट्रेसला स्पर्श केला आहे . , अंदाज लावा, java.lang.StackTraceElementवस्तू देखील अपरिवर्तनीय आहेत. याचा अर्थ होतो: जर कोणी आमच्या स्टॅकचा डेटा बदलू शकला, तर तो संपूर्ण गोष्ट निरर्थक करेल. कल्पना करा की कोणीतरी स्टॅक ट्रेसमधून जात आहे आणि OutOfMemoryError FileNotFoundException मध्ये बदलत आहे . आणि मग तुम्ही त्या स्टॅकचा वापर त्रुटीचे कारण शोधण्यासाठी करता. परंतु प्रोग्राम फायली देखील वापरत नाही. :) म्हणून, त्यांनी या वस्तू अपरिवर्तनीय बनवल्या. ठीक आहे, त्यामुळे StackTraceElement साठी हे कमी-अधिक प्रमाणात अर्थपूर्ण आहे . परंतु, कोणालाही स्ट्रिंग्स अपरिवर्तनीय बनविण्याची गरज का आहे? त्यांची मूल्ये बदलणे ही समस्या का असेल? हे कदाचित अधिक सोयीस्कर असेल. :/ याची अनेक कारणे आहेत. प्रथम, ते मेमरी वाचवते. अपरिवर्तनीय स्ट्रिंग स्ट्रिंग पूलमध्ये ठेवल्या जाऊ शकतात, नवीन तयार करण्याऐवजी स्ट्रिंगचा पुन्हा वापर करण्यास अनुमती देते. दुसरे, सुरक्षिततेसाठी. उदाहरणार्थ, वापरकर्तानाव आणि संकेतशब्द जवळजवळ प्रत्येक प्रोग्राममध्ये स्ट्रिंग आहेत. त्यांना बदलणे शक्य केल्याने अधिकृतता समस्या उद्भवू शकतात. इतरही कारणे आहेत, परंतु Java च्या आमच्या अभ्यासाने अद्याप ते समाविष्ट केलेले नाही, म्हणून आम्ही नंतर त्यांच्याकडे परत येऊ.