"अमिगो, तुला व्हेल आवडतात का?"

"व्हेल? नाही, त्यांच्याबद्दल कधीच ऐकले नाही."

"ती गायीसारखी आहे, फक्त मोठी आहे आणि ती पोहते आहे. योगायोगाने, व्हेल गायीतून आले आहेत. अहो, किंवा किमान त्यांचे पूर्वज समान आहेत. काही फरक पडत नाही."

बहुरूपता आणि अधिग्रहण - १

"ऐका. मला तुम्हाला OOP च्या आणखी एका शक्तिशाली साधनाबद्दल सांगायचे आहे: पॉलीमॉर्फिझम . यात चार वैशिष्ट्ये आहेत."

1) पद्धत अधिलिखित.

कल्पना करा की तुम्ही खेळासाठी "गाय" वर्ग लिहिला आहे. यात बरेच सदस्य व्हेरिएबल्स आणि पद्धती आहेत. या वर्गातील वस्तू विविध गोष्टी करू शकतात: चालणे, खाणे, झोपणे. गायीही चालताना घंटा वाजवतात. समजा तुम्ही वर्गातील प्रत्येक गोष्ट अगदी लहान तपशीलापर्यंत लागू केली आहे.

बहुरूपता आणि अधिलिखित - 2

मग अचानक ग्राहक म्हणतो की त्याला गेमचा एक नवीन स्तर सोडायचा आहे, जिथे सर्व क्रिया समुद्रात होतात आणि मुख्य पात्र एक व्हेल आहे.

तुम्ही व्हेल वर्गाची रचना करण्यास सुरुवात केली आणि लक्षात आले की ते गाय वर्गापेक्षा थोडे वेगळे आहे. दोन्ही वर्ग खूप समान तर्कशास्त्र वापरतात आणि तुम्ही वारसा वापरण्याचे ठरवता.

गाय वर्ग हा पालक वर्ग म्हणून योग्य आहे: त्यात आधीपासूनच सर्व आवश्यक चल आणि पद्धती आहेत. आपल्याला फक्त व्हेलची पोहण्याची क्षमता जोडण्याची आवश्यकता आहे. पण एक समस्या आहे: तुमच्या व्हेलला पाय, शिंगे आणि घंटा आहे. शेवटी, गाय वर्ग ही कार्यक्षमता लागू करतो. तुम्ही काय करू शकता?

बहुरूपता आणि अधिलिखित - 3

पद्धत ओव्हरराइडिंग बचावासाठी येते. आमच्या नवीन वर्गात आम्हाला आवश्यक तेच करत नसलेल्या पद्धतीचा वारसा मिळाल्यास, आम्ही दुसरी पद्धत बदलू शकतो.

बहुरूपता आणि अधिलिखित - 4

हे कसे केले जाते? आमच्या वंशज वर्गात, आम्ही जी पद्धत बदलू इच्छितो ती घोषित करतो (पालक वर्गात असलेल्या त्याच पद्धतीच्या स्वाक्षरीसह) . मग आम्ही पद्धतीसाठी नवीन कोड लिहितो. बस एवढेच. असे आहे की पालक वर्गाची जुनी पद्धत अस्तित्वात नाही.

ते कसे कार्य करते ते येथे आहे:

कोड वर्णन
class Cow
{
public void printColor()
{
System.out.println("I'm white");
}
public void printName()
{
System.out.println("I'm a cow");
}
}class Whale extends Cow
{
public void printName()
{
System.out.println("I'm a whale");
}
}
येथे आपण दोन वर्ग परिभाषित करतो:  Cow आणि  WhaleWhaleवारसा  Cow_

वर्ग  पद्धत Whale ओव्हरराइड करतो  printName();.

public static void main(String[] args)
{
Cow cow = new Cow();
cow.printName();
}
हा कोड स्क्रीनवर « मी एक गाय आहे » दाखवतो .
public static void main(String[] args)
{
Whale whale = new Whale();
whale.printName();
}
हा कोड स्क्रीनवर « मी व्हेल आहे » दाखवतो

तो वारसा घेतल्यानंतर Cowआणि ओव्हरराइड केल्यानंतर printName, Whaleवर्गामध्ये प्रत्यक्षात खालील डेटा आणि पद्धती असतात:

कोड वर्णन
class Whale
{
public void printColor()
{
System.out.println("I'm white");
}
public void printName()
{
System.out.println("I'm a whale");
}
}
आम्हाला कोणत्याही जुन्या पद्धतीबद्दल काहीच माहिती नाही.

"प्रामाणिकपणे, मला तेच अपेक्षित होते."

२) पण एवढेच नाही.

"समजा  Cow वर्गात एक  printAll, पद्धत आहे जी इतर दोन पद्धतींना कॉल करते. तर कोड याप्रमाणे कार्य करेल:"

स्क्रीन दर्शवेल:
मी पांढरा आहे
मी व्हेल आहे

कोड वर्णन
class Cow
{
public void printAll()
{
printColor();
printName();
}
public void printColor()
{
System.out.println("I'm white");
}
public void printName()
{
System.out.println("I'm a cow");
}
}

class Whale extends Cow
{
public void printName()
{
System.out.println("I'm a whale");
}
}
public static void main(String[] args)
{
Whale whale = new Whale();
whale.printAll();
}
स्क्रीन दर्शवेल:
मी पांढरा आहे
मी व्हेल आहे

लक्षात ठेवा जेव्हा व्हेल ऑब्जेक्टवर काउ क्लासची प्रिंटऑल () पद्धत कॉल केली जाते, तेव्हा व्हेलची प्रिंटनेम() पद्धत वापरली जाईल, गायची नाही.

महत्त्वाची गोष्ट म्हणजे पद्धत ज्या वर्गात लिहिली आहे ती नाही, तर ज्या ऑब्जेक्टवर पद्धत म्हटली आहे त्याचा प्रकार (वर्ग) आहे.

"मी बघतो."

"तुम्ही फक्त नॉन-स्टॅटिक पद्धतींचा वारसा आणि अधिलिखित करू शकता. स्थिर पद्धती वारशाने मिळत नाहीत आणि त्यामुळे अधिलिखित करता येत नाहीत."

आम्ही वारसा लागू केल्यानंतर आणि पद्धती अधिलिखित केल्यानंतर व्हेल वर्ग कसा दिसतो ते येथे आहे:

कोड वर्णन
class Whale
{
public void printAll()
{
printColor();
printName();
}
public void printColor()
{
System.out.println("I'm white");
}
public void printName()
{
System.out.println("I'm a whale");
}
}
आम्ही वारसा लागू केल्यानंतर आणि पद्धत अधिलिखित केल्यानंतर व्हेल वर्ग कसा दिसतो ते येथे आहे. आम्हाला कोणत्याही जुन्या printNameपद्धतीबद्दल काहीच माहिती नाही.

3) कास्टिंग टाइप करा.

येथे आणखी एक मनोरंजक मुद्दा आहे. क्लासला त्याच्या पॅरेंट क्लासच्या सर्व पद्धती आणि डेटाचा वारसा मिळत असल्याने, या क्लासच्या ऑब्जेक्टचा संदर्भ पॅरेंट क्लासच्या व्हेरिएबल्सद्वारे केला जाऊ शकतो (आणि मूळचा पालक इ., ऑब्जेक्ट क्लासपर्यंत). या उदाहरणाचा विचार करा:

कोड वर्णन
public static void main(String[] args)
{
Whale whale = new Whale();
whale.printColor();
}
स्क्रीन दर्शवेल:
मी पांढरा आहे.
public static void main(String[] args)
{
Cow cow = new Whale();
cow.printColor();
}
स्क्रीन दर्शवेल:
मी पांढरा आहे.
public static void main(String[] args)
{
Object o = new Whale();
System.out.println(o.toString());
}
स्क्रीन दर्शवेल:
Whale@da435a.
toString() पद्धत ऑब्जेक्ट क्लासमधून इनहेरिट केलेली आहे.

"चांगले सामान. पण तुला याची गरज का पडेल?"

"हे एक मौल्यवान वैशिष्ट्य आहे. तुम्हाला नंतर समजेल की ते खूप, खूप मौल्यवान आहे."

4) लेट बाइंडिंग (डायनॅमिक डिस्पॅच).

ते कसे दिसते ते येथे आहे:

कोड वर्णन
public static void main(String[] args)
{
Whale whale = new Whale();
whale.printName();
}
स्क्रीन दर्शवेल:
मी व्हेल आहे.
public static void main(String[] args)
{
Cow cow = new Whale();
cow.printName();
}
स्क्रीन दर्शवेल:
मी व्हेल आहे.

लक्षात घ्या की आपण कोणत्या विशिष्ट प्रिंटनेम पद्धतीला (गाय किंवा व्हेल वर्ग) म्हणतो ते व्हेरिएबलचा प्रकार नाही , तर व्हेरिएबलद्वारे संदर्भित ऑब्जेक्टचा प्रकार आहे.

गाय व्हेरिएबल व्हेल ऑब्जेक्टचा संदर्भ संग्रहित करते आणि व्हेल क्लासमध्ये परिभाषित केलेल्या प्रिंटनेम पद्धतीला कॉल केले जाईल.

"बरं, त्यांनी स्पष्टतेसाठी ते जोडले नाही."

"हो, हे इतके स्पष्ट नाही. हा महत्त्वाचा नियम लक्षात ठेवा:"

तुम्ही व्हेरिएबलवर कॉल करू शकता अशा पद्धतींचा संच व्हेरिएबलच्या प्रकारानुसार निर्धारित केला जातो. परंतु कोणती विशिष्ट पद्धत/अंमलबजावणी कॉल केली जाते हे व्हेरिएबलद्वारे संदर्भित ऑब्जेक्टच्या प्रकार/वर्गाद्वारे निर्धारित केले जाते.

"मी प्रयत्न करेन."

"तुम्ही यात सतत धावत असाल, त्यामुळे तुम्हाला ते पटकन समजेल आणि कधीही विसरता येणार नाही."

5) कास्टिंग टाइप करा.

कास्टिंग हे आदिम प्रकारांपेक्षा संदर्भ प्रकारांसाठी, म्हणजे वर्गांसाठी वेगळ्या पद्धतीने कार्य करते. तथापि, रुंदीकरण आणि संकुचित रूपांतरणे संदर्भ प्रकारांवर देखील लागू होतात. या उदाहरणाचा विचार करा:

रुंदीकरण रूपांतरण वर्णन
Cow cow = new Whale();

एक क्लासिक रुंदीकरण रूपांतरण. आता तुम्ही व्हेल ऑब्जेक्टवरील गाय वर्गामध्ये परिभाषित केलेल्या पद्धतींना कॉल करू शकता.

कंपायलर तुम्हाला गाय व्हेरिएबलचा वापर फक्त गाय प्रकाराद्वारे परिभाषित केलेल्या पद्धतींना कॉल करण्यासाठी करू देईल.

संकुचित रूपांतरण वर्णन
Cow cow = new Whale();
if (cow instanceof Whale)
{
Whale whale = (Whale) cow;
}
प्रकार तपासणीसह क्लासिक अरुंद रूपांतरण . गाय प्रकारातील गाय व्हेरिएबल व्हेल ऑब्जेक्टचा संदर्भ साठवते.
आम्ही तपासतो की हे केस आहे , आणि नंतर (विस्तृत) प्रकार रूपांतरण करा. याला प्रकार कास्टिंग देखील म्हणतात .
Cow cow = new Cow();
Whale whale = (Whale) cow; //exception
तुम्ही ऑब्जेक्ट टाइप-तपासल्याशिवाय संदर्भ प्रकाराचे संकुचित रूपांतरण देखील करू शकता.
या प्रकरणात, जर गाय व्हेरिएबल व्हेल ऑब्जेक्ट व्यतिरिक्त इतर गोष्टीकडे निर्देश करत असेल, तर अपवाद (InvalidClassCastException) टाकला जाईल.

6) आणि आता चवदार काहीतरी. मूळ पद्धत कॉलिंग.

कधीकधी वारसा मिळालेली पद्धत ओव्हरराइड करताना तुम्हाला ती पूर्णपणे बदलायची नसते. काहीवेळा आपल्याला त्यात थोडेसे जोडायचे आहे.

या प्रकरणात, तुम्हाला नवीन पद्धतीचा कोड त्याच पद्धतीवर कॉल करायचा आहे, परंतु बेस क्लासवर. आणि जावा आपण हे करू. हे असे केले जाते:  super.method().

येथे काही उदाहरणे आहेत:

कोड वर्णन
class Cow
{
public void printAll()
{
printColor();
printName();
}
public void printColor()
{
System.out.println("I'm white");
}
public void printName()
{
System.out.println("I'm a cow");
}
}

class Whale extends Cow
{
public void printName()
{
System.out.print("This is false: ");
super.printName();

System.out.println("I'm a whale");
}
}
public static void main(String[] args)
{
Whale whale = new Whale();
whale.printAll();
}
स्क्रीन दर्शवेल:
मी पांढरा आहे
हे खोटे आहे: मी एक गाय आहे
मी व्हेल आहे

"हम्म. तो काही धडा होता. माझे रोबोट कान जवळजवळ वितळले."

"होय, ही काही साधी गोष्ट नाही. ही काही सर्वात कठीण सामग्री आहे जी तुम्हाला भेटेल. प्राध्यापकांनी इतर लेखकांच्या सामग्रीचे दुवे देण्याचे वचन दिले आहे, जेणेकरुन तुम्हाला अजूनही काही समजत नसेल, तर तुम्ही ते भरू शकता. अंतर."