Inheritance in C# with Example

Masking or Hiding the Base Class Members in Derived Class

कोई भी Derived Class उस Class के किसी Member को Delete नहीं कर सकता है, जिसे उसने Inherit किया है। लेकिन Derived Class अपने Base Class के किसी Member को Current Class में समान नाम से Declare करके Mask कर सकता है। C# द्वारा Provide किया जाने वाला ये एक काफी उपयोगी और जरूरी Feature है।

उदाहरण के लिए हमारे पास एक Base Class हो सकती है, जिसमें कोई Particular Method हो सकता है। ये Method उस Class के लिए भी पूरी तरह से उपयुक्त हो सकता है, जिसमें इसे Declare किया गया है, लेकिन जब हम इसे Derived Class में प्राप्त करते हैं, तो Derived Class में ये Method Exactly वही काम करे जिसके लिए इसे Define किया गया है, ऐसा जरूरी नहीं होता।

इस प्रकार की स्थिति में हम इस Method को अपने Derived Class में Mask कर सकते हैं और Derived Class में समान नाम का Member Define कर सकते हैं।

उदाहरण के लिए जब हम Base Class के किसी Data Member को Mask करना चाहते हैं, तो हम Derived Class में समान Type व समान नाम का एक नया Member Declare करते हैं। इसी तरह से जब हम Base Class के किसी Method को Mask करना चाहते हैं, तो हम Derived Class में समान Signature का Method Define करते हैं।

C# Compiler को ये बताने के लिए कि हम किसी Specific जरूरत को पूरा करने के लिए Inherited Members की Masking कर रहे हैं, हम Derived Class में Members को Declare करते समय new Keyword का प्रयोग करते हैं। इतना ही नहीं, यदि हम चाहें तो अपनी जरूरत के अनुसार हम किसी Static Member की भी Masking कर सकते हैं।

हालांकि यदि हम new Keyword का प्रयोग नहीं करते हैं, तब भी C# Compiler हमारे Program को बिना किसी Error के Run करता है, लेकिन इस स्थिति में C# Compiler हमें एक Warning देता है कि हम किसी Inherited Member को Hide कर रहे हैं। इस Concept को समझने के लिए हम हमारे पिछले Program को ही निम्नानुसार Modify कर सकते हैं:

File Name: BaseClassInheritedMembersMaskingInDerivedClass.cs
using System;

namespace CSharpInterface
{
    class Time
    {
        public byte hour { set; get; }
        public byte minute { set; get; }

        public void SetTime(byte hour, byte minute)
        {
            this.hour = hour;
            this.minute = minute;
        }

        public void DisplayTime()
        {
            Console.Write(hour + ":" + minute);
        }
    }

    class NewTime : Time
    {
        new public byte hour { get; set; }
        new public byte minute { get; set; }

        public byte second { set; get; }

        public void SetTime(byte hour, byte minute, byte second)
        {
            this.hour = hour;
            this.minute = minute;
            this.second = second;
        }

        new public void DisplayTime()
        {
            Console.Write(hour + ":" + minute + ":" + second);
        }
    }

    class UsingTime
    {
        static void Main(String[] arg)
        {

            Console.WriteLine("Base Time Class");
            Time hmt = new Time();
            hmt.SetTime(12, 22);
            Console.Write("Time of HMT: ");
            hmt.DisplayTime();

            Console.WriteLine("\n\nDerived Time Class");
            NewTime sonata = new NewTime();
            Console.Write("Time of SONATA: ");
            sonata.SetTime(10, 15, 30);
            sonata.DisplayTime();
        }
    }
}

// Output:
   Base Time Class
   Time of HMT: 12:22

   Derived Time Class
   Time of SONATA: 10:15:30

इस Program में हमने हमारी NewTime नाम की Derived Class में भी निम्नानुसार Statements द्वारा new Operator का प्रयोग करते हुए hourminute नाम की Properties Create कर दिया है:

new public byte hour { get; set; }
new public byte minute { get; set; }

साथ ही निम्नानुसार तरीके से SetTime() के Code को भी Change कर दिया है तथा DisplayTime() Methods को भी new Keyword के साथ Specify करते हुए Modify कर दिया है:

        public void SetTime(byte hour, byte minute, byte second)
        {
            this.hour = hour;
            this.minute = minute;
            this.second = second;
        }

        new public void DisplayTime()
        {
            Console.Write(hour + ":" + minute + ":" + second);
        }

इसलिए इस बार जब हम sonata Object Create करते हैं, तो हमारा hourminute का Data Base Class के hourminute Property में Store नहीं होताए बल्कि NewTime Class के hourminute नाम की Masked Properties में ही Store हो जाता है।

साथ ही जब हम SetTime() Method को Call करते हैं, तो NewTime Class का ही SetTime() Method Call होता है, जबकि DisplayTime() Method Time Class के DisplayTime() Method को Mask कर रहा है।

इस तरह से यदि हम सारांश में समझें तो हालांकि हम NewTime Class को Time Class से Derive कर रहे हैं, लेकिन फिर भी NewTime Class, Time Class से पूरी तरह से अलग है, क्योंकि हम इस NewTime Class में Time Class की किसी भी Inherited Property या Method को NewTime Class के Object के लिए Use नहीं कर रहे हैं, बल्कि NewTime Class की सभी PropertiesMethods Base Class से अलग हैं।

Base Class Accessing in Derived Class

हालांकि हम पिछले उदाहरण के अनुसार Code लिखकर Derived Class में Inherit होने वाले विभिन्न Base Class Members को Hide या Mask कर सकते हैं। लेकिन फिर भी यदि हमें Mask किए गए Members के अलावा Derived Class में Base Class के Members को भी Access करने की जरूरत हो, तो हम base Keyword के साथ Dot Operator का प्रयोग करते हुए Member को Specify करके किसी Specific Base Class Member को Access कर सकते हैं। जैसे:

File Name: AccessingBaseClassMemberInMaskedDerivedClass.cs
using System;

namespace CSharpInterface
{
    class Time
    {
        public byte hour { set; get; }
        public byte minute { set; get; }

        public void SetTime(byte hour, byte minute)
        {
            this.hour = hour;
            this.minute = minute;
        }

        public void DisplayTime()
        {
            Console.Write(hour + ":" + minute);
        }
    }

    class NewTime : Time
    {
        public byte second { set; get; }

        public void SetTime(byte hour, byte minute, byte second)
        {
            SetTime(hour, minute);
            this.second = second;
        }

        new public void DisplayTime()
        {
            base.DisplayTime();
            Console.Write(":" + second);
        }
    }

    class UsingTime
    {
        static void Main(String[] arg)
        {

            Console.WriteLine("Base Time Class");
            Time hmt = new Time();
            hmt.SetTime(12, 22);
            Console.Write("Time of HMT: ");
            hmt.DisplayTime();

            Console.WriteLine("\n\nDerived Time Class");
            NewTime sonata = new NewTime();
            Console.Write("Time of SONATA: ");
            sonata.SetTime(10, 15, 30);
            sonata.DisplayTime();
        }
    }
}

// Output:
   Base Time Class
   Time of HMT: 12:22

   Derived Time Class
   Time of SONATA: 10:15:30

चूंकि इस Program में SetTime() Method Override किया गया है, इसलिए दोनों Classes के SetTime() Method का Signature अलग होने की वजह से C# Compiler तय कर लेता है, कि उसे किस Class के Object के लिए किस Class के SetTime() Method को Call करना है। लेकिन यदि हम इस Program के DisplayTime() Method को देखें, जो कि निम्नानुसार है:

        new public void DisplayTime()
        {
            base.DisplayTime();
            Console.Write(":" + second);
        }

तो हम समझ सकते हैं कि हालांकि Base Class व Derived Class दोनों में ही Specify किए गए DisplayTime() Method का Signature एक समान है, फिर भी ये Program Normal तरीके से काम करता है, क्योंकि DisplayTime() Method की Masking करते हुए हमने इस Masked DisplayTime() Method में base Keyword के साथ निम्नानुसार Statement द्वारा DisplayTime() Method को Specify किया है:

base.DisplayTime();

जिसकी वजह से इस बार जब ये Program Run होता है, तो Derived Class के लिए DisplayTime() Method को बार-बार Recursive तरीके से Execute नहीं करताए बल्कि C# Compiler को base Keyword के कारण पता चल जाता है कि उसे Base Class के DisplayTime() Method को Call करना है। परिणामस्वरूप इस तरीके का प्रयोग करके हम DisplayTime() Method की भी Overriding करने की सुविधा प्राप्त कर लेते हैं।

Using References to Base Class

चूंकि Derived Class के Object में Base Class के Instance के अलावा स्वयं के भी Additional Members होते हैं। इसलिए Derived Class का Reference पूरे Class Object को Point करता है, जिसमें Base Class का Instance भी Included होता है।

इसलिए यदि हमारे पास किसी Derived Class के Object का Reference हो, तो हम उस Derived Class के Object के Reference के माध्‍यम से उसके Base Class के Part को Cast Operator का प्रयोग करते हुए Casting करके प्राप्त कर सकते हैं। जैसे:

MyDerivedClass derivedObject = new MyDerivedClass();     // Create an Object.
MyBaseClass baseObject = (MyBaseClass) derived;                // Cast the Reference.

इस Code Segment में First Line MyDerivedClass Type का एक Object Create करता है, जिसका Reference derivedObject नाम के Reference में Store होता है। जबकि दूसरी Line का Code MyBaseClass Type का एक Reference Create करता है और derivedObject द्वारा Referenced Object की Casting करते हुए Base Class के Part के Reference को Return करके baseObject में Store कर देता है।

परिणामस्वरूप baseObject वास्तव में derivedObject के MyBaseClass Part को Reference करने लगता है। इस पूरी व्‍यवस्था को हम निम्न चित्र द्वारा ज्यादा बेहतर तरीके से Represent कर सकते हैं:

Inheritance in C# with Example - Hindi

हम किसी Derived Class में स्थित Base Class के Part को Casting के माध्‍यम से Base Class के Reference के माध्‍यम से Point कर सकते हैं, इस बात को समझने के लिए हम निम्नानुसार एक Program Create कर सकते हैं:

File Name: BaseReferenceDerivedObject.cs
using System;

namespace CSharpInterface
{
    class Time
    {
// Same as previous program
    }

    class NewTime : Time
    {
// Same as previous program
    }

    class UsingTime
    {
        static void Main(String[] arg)
        {
            Console.WriteLine("\nDerived Time Class");
            NewTime sonata = new NewTime();
            Console.Write("Time of SONATA: ");
            sonata.SetTime(10, 15, 30);
            sonata.DisplayTime();

            Console.WriteLine("\n\nBase Time Class");
            Time hmt = (Time)sonata;
            hmt.SetTime(12, 22);
            Console.Write("Time of HMT: ");
            hmt.DisplayTime();

            Console.WriteLine("\n\nAfter modifying Base Part of Derived NewTime");
            Console.Write("Time of SONATA: ");
            sonata.DisplayTime();
        }
    }
}

// Output:
   Derived Time Class
   Time of SONATA: 10:15:30

   Base Time Class
   Time of HMT: 12:22

   After modifying Base Part of Derived NewTime
   Time of SONATA: 12:22:30

जैसाकि इस Program के Output द्वारा हम समझ सकते हैं कि इस Program में जब हम Derived Class के Object के Base Class के Part को निम्नानुसार Casting करके Base Class के Reference में Store करते हैं:

Time hmt = (Time)sonata;

और इस hmt नाम के Reference Variable द्वारा sonata नाम के Derived Class के Object के Base Part को निम्नानुसार Statement द्वारा Modify करते हैं:

hmt.SetTime(12, 22);

तो जब हम दुबारा sonata Object के Time को Display करते हैं, तो हमें वही Time प्राप्त नहीं होताए जो पहले प्राप्त हो रहा था, बल्कि इस बार प्राप्त होने वाला Hour व Minute Change हो चुके होते हैं, जबकि हमने sonata द्वारा Referenced Hour व Minute के मान को नहीं बल्कि hmt द्वारा Referenced Hour व Minute के मान को Change किया है।

hmt के hourminute के मान को Change करने पर sonata के मान का Change होना इसी बात का Indication है कि hmt वास्तव में sonata Object के ही Base Class Part को Reference कर रहा है, न कि किसी नए Memory Area को।

Inheritance in C#
Polymorphism in C#

C# in Hindiये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

C#.NET in Hindi | Page:908 | Format: PDF

BUY NOW GET DEMO REVIEWS