यह बहुरूपता के पीछे मौलिक सिद्धांत है। प्रत्येक ऑब्जेक्ट का प्रकार अभिव्यक्ति के बाईं ओर दिखाई देता है, हालांकि, यह दायीं तरफ जो भी हो, कार्य करेगा। उदाहरण के लिए, तो जैसे एक समारोह का सोचते हैं: अब
public static void Claw(Cat cat)
{
cat.claw();
}
, हम यह मान हमारे कक्षाओं कुछ की तरह हैं:
Cat c = new Cat();
Cat j = new JungleCat();
पासिंग:
public class Cat
{
//...
public void claw()
{
System.out.println("Cat claw");
}
}
public class JungleCat extends Cat
{
//...
@Override
public void claw()
{
System.out.println("Jungle cat claw");
}
}
अब, चलो कुछ वस्तुओं instanstiate जाने हमारे static Claw
फ़ंक्शन में:
Claw(c); //Prints "Cat claw"
Claw(j); //Prints "Jungle cat claw"
,
public static void Claw(JungleCat junglecat)
{
junglecat.claw();
}
फिर Claw(c)
स्पष्ट रूप से संकलन नहीं होगा, क्योंकि यह एक Cat
है:
मान लें हम तो जैसे समारोह को संशोधित किया। Claw(j)
के बारे में क्या? यह संकलित नहीं होगा, जैसा कि हमने कहा है कि यह Cat
प्रकार भी है। हम जानते हैं कि यह वास्तव में JungleCat
है, लेकिन हमने संकलक को बताया है "ठीक है, बस इसका इलाज करें जैसे यह सामान्य Cat
प्रकार है"।
इन शुरुआती उदाहरणों में अक्सर क्या खो रहा है क्यों कोई ऐसा करना चाहेगा। बिल्लियों और जानवरों और जैसे अक्सर खराब उदाहरण होते हैं। एक बेहतर उदाहरण के लिए, मान लें कि हमारे पास कुछ कोड है जो विभिन्न ऑपरेटिंग सिस्टम के आधार पर अलग-अलग चीजों को करने के लिए है; चारों ओर एक फाइल ले जाने कहते हैं। यदि यह Linux
पर चलता है, तो हम फ़ाइल को /usr/bin
पर ले जाना चाहते हैं, अगर यह विंडोज़ पर है, C:\Windows\System32
। इसलिए हम तो जैसे एक इंटरफेस को परिभाषित:
public interface FileMover
{
public void move(File f);
}
public class LinuxMover implements FileMover
{
public void move(File f)
{
//Move our file to /usr/bin
}
}
public class WindowsMover implements FileMover
{
public void move(File f)
{
//Move our file to C:\Windows\System32
}
}
अब, हम नहीं जानते कि जो प्रणाली के लिए इस कोड को चलाने के लिए जब तक क्रम जा रहा है - तो हम एक क्रम की जांच उचित वर्ग रनटाइम पर करते हैं और दृष्टांत कर सकते हैं:
वे परवाह नहीं है
तरह क्या - - इसलिए हम दो कार्यशील परिभाषाएँ हर बार लिखने के लिए नहीं है हम
FileMover
, जैसे एक अलग तरह का उपयोग करना चाहते
//Pseudocode
FileMover fm;
if(OperatingSystem == LINUX) {
fm = new LinuxMover();
}
else if(OperatingSystem == WINDOWS) {
fm = new WindowsMover();
}
fm.move();
इसी तरह, किसी भी काम करता है बस एक FileMover
ले जा सकते हैं doSomething(WindowsFileMover m)
और doSomething(LinuxFileMover m)
, हम बस प्रतिलिपि बना सकते हैं यह एक समारोह doSomething(FileMover m)
के साथ, सही प्रकार में पास करें, और यह "बस काम करेगा"।
यह संभवतः प्रश्न की आवश्यकता के मुकाबले बहुत अधिक जानकारी है, लेकिन उम्मीद है कि यह आपको कुछ अंतर्ज्ञान भी देता है कि सामान्य बिल्लियों और कुत्तों की तुलना में कुछ और ठोस तरीके से ऐसी चीजें क्यों की जाती हैं।
* ऑब्जेक्ट * का प्रकार आवश्यक वैरिएबल के प्रकार के समान नहीं है (या अभिव्यक्ति जिसे अन्यथा उपयोग किया जाता है)। इस पर विचार करें: 'ऑब्जेक्ट str = "हैलो"; '- * ऑब्जेक्ट * का प्रकार' str' को असाइन किया गया है? * अभिव्यक्ति * 'str' का प्रकार क्या है? –