Sunday, 3 February 2019

Interview Questions on Inheritance.

Inheritance
Inheritance is one of the three foundational principles of object-oriented programming because it allows the creation of hierarchical classifications. Using inheritance, you can create a general class that defines traits common to a set of related items. This class can then be inherited by other, more specific classes, each adding those things that are unique to it. In the language of C#, a class that is inherited is called a base class. The class that does the inheriting is called a derived class. Therefore, a derived class is a specialized version of a base class. It inherits all of the variables, methods, properties, and indexers defined by the base class and adds its own unique elements.
using System;

namespace inheritance_Examples
{
    class Shape
    {
        public double Width=0.0;
        public double Height=0.0;
        public void ShowDim()
        {
            Console.WriteLine("Width and height are " + Width + " and " + Height);
        }
    } 
    
    // Triangle is derived from TwoDShape. 
    class Triangle : Shape
    {
        public string Style; // style of triangle  
        public double Area() // Return area of triangle. 
        {
            return Width * Height / 2;
        }  

        // Display a triangle's style. 
        public void ShowStyle()
        {
            Console.WriteLine("Triangle is " + Style);
        }
    }
    class Shapes
    {
        static void Main()
        {
            Triangle t1 = new Triangle();
            Triangle t2 = new Triangle();

            t1.Width = 4.0;             // declared in base class
            t1.Height = 4.0;            // declared in base class
            t1.Style = "isosceles";     // declared in derived class

            t2.Width = 8.0;         
            t2.Height = 12.0;
            t2.Style = "right";
            Console.WriteLine("Info for t1: ");

            t1.ShowStyle();             // derived class method is called
            t1.ShowDim();               // base calss method is called

            Console.WriteLine("Area is " + t1.Area()); //Derived class method 
            Console.WriteLine();

            Console.WriteLine("Info for t2: ");
            t2.ShowStyle();
            t2.ShowDim();
            Console.WriteLine("Area is " + t2.Area());

            Console.ReadLine();
        }
    }
}

You can specify only one base class for any derived class that you create. C# does not support the inheritance of multiple base classes into a single derived class. See the below code:
namespace inheritance_Examples
{
    class Test
    {
    }
 
    class A
    {
 
    }
 
    class BTestA
    {
 
    }
}

Code
Description
File
CS1721
Class 'B' cannot have multiple base classes: 'Test' and 'A'
E:\inheritance Examples\inheritance Examples\Test.cs

You can, create a hierarchy of inheritance in which a derived class becomes a base class of another derived class.
namespace inheritance_Examples
{
    class Test
    {
    }
 
    class A:Test
    {
 
    }
 
    class BA
    {
 
    }
 
    class CB
    {
 
    }
}

Accessing instance variables, methods, properties, and indexers
No class can be a base class of itself, either directly or indirectly.
A derived class inherits all of the members of its base class. This includes instance variables, methods, properties, and indexers.
using System;
using System.Collections.Generic;
using System.Text;
 
namespace inheritance_Examples
{
    class Test
    {
        public string Name = string.Empty;  //Instance Variable
        double salary = 1000;               //Private Variable
        public string ShowName()          // Instance Method
        {
            return (Name);
        }
 
        public double GetSal  //Property declared to access private field
        {
            get { return salary; }
            set { salary = value; }
        }
 
 
        private string[] range = new string[5]; // Indexers
        public string this[int indexrange]
        {
            get
            {
                return range[indexrange];
            }
            set
            {
                range[indexrange] = value;
            }
        }
    }
 
    class A:Test
    {
 
    }
 
    class ATest
    {
            public static void Main()
            {
                A obj = new A
                {
                    Name = "A G Kumar" //Instance varibale called 
                };
 
                obj.ShowName();         //Instance method called
                
                //Private field salary is called using property GetSal
                Console.WriteLine("Salary Is :" + obj.GetSal); 
 
                //Indexer is called
                obj[0] = "ONE";
                obj[1] = "TWO";
                obj[2] = "THREE";
                obj[3] = "FOUR ";
                obj[4] = "FIVE";
               
                Console.WriteLine("{0}\n,{1}\n,{2}\n,{3}\n,{4}\n", obj[0], obj[1], obj[2], obj[3], obj[4]);
                Console.WriteLine("\n");
                Console.ReadLine();
            }
        }
    }
 
A major advantage of inheritance is that once you have created a base class that defines the attributes common to a set of objects, it can be used to create any number of more specific derived classes. Each derived class can precisely tailor its own classification. See the highlighted code:
using System;
 
namespace inheritance_Examples
{
    class Shape
    {
        public double Width=0.0;
        public double Height=0.0;
        public void ShowDim()
        {
            Console.WriteLine("Width and height are " + Width + " and " + Height);
        }
    } 
    
    // Triangle is derived from Shape. 
    class Triangle : Shape
    {
        public string Style; 
        public double Area()
        {
            return Width * Height / 2;
        }  
        public void ShowStyle()
        {
            Console.WriteLine("Triangle is " + Style);
        }
    }
 
    // Rectangle is derived from Shape. 
    class Rectangle : Shape
    {
        public bool IsSquare()
        {
            if (Width == Height) return truereturn false;
        }
        
        public double Area()
        {
            return Width * Height;
        }
    }
    class Program
    {
        static void Main()
        {
            Triangle t1 = new Triangle();
            Rectangle t2 = new Rectangle();
 
            t1.Width = 4.0;             // declared in base class
            t1.Height = 4.0;            // declared in base class
            t1.Style = "isosceles";     // declared in derived class
 
            t2.Width = 8.0;         
            t2.Height = 12.0;
            Console.WriteLine("Info for t1: ");
 
            t1.ShowStyle();             // derived class method is called
            t1.ShowDim();               // base calss method is called
 
            // Derived class method is called
            Console.WriteLine("Area is " + t1.Area()); 
            Console.WriteLine();
 
            Console.WriteLine("Info for t2: ");
            t2.IsSquare();
            t2.Area();
            Console.WriteLine("Area is " + t2.Area());
 
            Console.ReadLine();
        }
    }
}

Private members in Inheritance
Members of a class are often declared private to prevent their unauthorized use or tampering. Inheriting a class does not overrule the private access restriction. Thus, even though a derived class includes all of the members of its base class, it cannot access those members of the base class that are private.
A private class member will remain private to its class. It is not accessible to any code outside its class, including derived classes.
Derived classes do not have access to the private members of base classes. However, this is not true; C# provides various solutions. One is to use protected members.
A second is to use public properties to provide access to private data. See the highlighted code.
using System;
using System.Collections.Generic;
using System.Text;
 
namespace inheritance_Examples
{
    class Test
    {
        public string Name = string.Empty;  //Instance Variable
        double salary = 1000;               //Private Variable
        public string ShowName()            // Instance Method
        {
            return (Name);
        }
 
        public double GetSal  // Property declared to access private field
        {
            get { return salary; }
            set { salary = value; }
        }
 
        private string[] range = new string[5];
        public string this[int indexrange]
        {
            get
            {
                return range[indexrange];
            }
            set
            {
                range[indexrange] = value;
            }
        }
    }
 
    class A:Test
    {
 
    }
 
    class ATest
    {
            public static void Main()
            {
                A obj = new A
                {
                    Name = "A G Kumar" //Instance varibale called 
                };
 
                obj.ShowName();         //Instance method called
                
                //Private field salary is called using property GetSal
                Console.WriteLine("Salary Is :" + obj.GetSal); 
 
                //Property is called
                obj[0] = "ONE";
                obj[1] = "TWO";
                obj[2] = "THREE";
                obj[3] = "FOUR ";
                obj[4] = "FIVE";
               
                Console.WriteLine("{0}\n,{1}\n,{2}\n,{3}\n,{4}\n", obj[0], obj[1], obj[2], obj[3], obj[4]);
                Console.WriteLine("\n");
                Console.ReadLine();
            }
        }
    }
 
Protected Members in Inheritance
A private member of a base class is not accessible to a derived class. This would seem to imply that if you wanted a derived class to have access to some member in the base class, it would need to be public. Of course, making the member public also makes it available to all other code, which may not be desirable. Fortunately, this implication is untrue because C# allows you to create a protected member. A protected member is public within a class hierarchy, but private outside that hierarchy.
A protected member is created by using the protected access modifier. When a member of a class is declared as protected, that member is, with one important exception, private. The exception occurs when a protected member is inherited. In this case, a protected member of the base class becomes a protected member of the derived class and is, therefore, accessible to the derived class. Therefore, by using protected, you can create class members that are private to their class but that can still be inherited and accessed by a derived class.
class A
{
    protected int x = 123;
}

class B : A
{
    static void Main()
    {
        A a = new A();
        B b = new B();

        // Error CS1540, because x can only be accessed by
        // classes derived from A.
        // a.x = 10;

        // OK, because this class derives from A.
        b.x = 10;
    }
}
Like public and private, protected status stays with a member no matter how many layers of inheritance are involved. Therefore, when a derived class is used as a base class for another derived class, any protected member of the initial base class that is inherited by the first derived class is also inherited as protected by a second derived class.
using System;
using System.Collections.Generic;
using System.Text;
 
namespace inheritance_Examples
{
    class ProtectedTest
    {
        protected int x = 123;
    }
 
    class PA:ProtectedTest
    {
        protected int y = 125;
    }
 
    class ProgramTest:PA
    {
        static void Main()
        {
            ProgramTest pt = new ProgramTest();
            Console.WriteLine(pt.x);
            Console.WriteLine(pt.y);
 
            PA paObj = new PA();
            int res=paObj.x;  //Error
            int res1 = paObj.y; //Error
 
            Console.ReadLine();
          
        }
    }
}

Code
Description
File
CS1540
Cannot access protected member 'PA.y' via a qualifier of type 'PA'; the qualifier must be of type 'ProgramTest' (or derived from it)
E:\inheritance Examples\inheritance Examples\ProtectedTest.cs
CS1540
Cannot access protected member 'ProtectedTest.x' via a qualifier of type 'PA'; the qualifier must be of type 'ProgramTest' (or derived from it)
E:\inheritance Examples\inheritance Examples\ProtectedTest.cs

Although protected access is quite useful, it doesn’t apply in all situations. Use protected when you want to create a member that is accessible throughout a class hierarchy, but otherwise private. To manage access to a value, use a property.
Constructors and Inheritance
In a hierarchy, it is possible for both base classes and derived classes to have their own constructors.
This raises an important question: What constructor is responsible for building an object of the derived class? The one in the base class, the one in the derived class, or both?
Here is the answer: The constructor for the base class constructs the base class portion of the object, and the constructor for the derived class constructs the derived class part. This makes sense because the base class has no knowledge of or access to any element in a derived class. Thus, their construction must be separate. The preceding examples have relied upon the default constructors created automatically by C#, so this was not an issue. However, in practice, most classes will define constructors.
using System;
 
namespace inheritance_Examples
{
    class A
    {
        public A()
        {
            Console.WriteLine("Base class Default Constructor");
        }
    }
 
    class B:A
    {
        public B()
        {
            Console.WriteLine("Derived Class constructor");
        }
    }
 
    class Program
    {
        static void Main()
        {
            B obj = new B();
            Console.ReadLine();
        }
    }
}

Output:
Base class Default Constructor
Derived Class constructor
When only the derived class defines a constructor, the process is straightforward: Simply construct the derived class object. The base class portion of the object is constructed automatically using its default constructor.
using System;
 
namespace inheritance_Examples
{
    class A
    {
     
    }
 
    class B:A
    {
        public B()
        {
            Console.WriteLine("Derived Class constructor");
        }
    }
 
    class CB
    {
        public C()
        {
            Console.WriteLine("Constructor of C Class");
        }
    }
    class Program
    {
        static void Main()
        {
            C obj = new C();
            Console.ReadLine();
        }
    }
}


Output:
Derived Class constructor
Constructor of C Class
Calling Base Class Constructors
When both the base class and the derived class define constructors, the process is a bit more complicated because both the base class and derived class constructors must be executed. In this case, you must use another of C#’s keywords, base, which has two uses. The first use is to call a base class constructor. The second is to access a member of the base class that has been hidden by a member of a derived class.
using System;
 
namespace inheritance_Examples
{
    class A
    {
        public int _a, _b;
        public A(int a, int b)
        {
            _a = a;
            _b = b;
        }
 
        public void ShowA()
        {
            Console.WriteLine("a :" + _a + "\n b:" + _b);
        }
    }
 
    class B:A
    {
        public int _c;
        public B(int a,int b,int c): base(a,b)
        {
            _c = c;
        }
 
        public void ShowB()
        {
            Console.WriteLine("a :" + _a + "\n b:" + _b);
        }
    }
 
    class Program
    {
        static void Main()
        {
            B obj = new B(5,6,7);
            obj.ShowA();
            obj.ShowB();
 
            Console.ReadLine();
        }
    }
}

When a derived class specifies a base clause, it is calling the constructor of its immediate base class. Thus, base always refers to the base class immediately above the calling class. This is true even in a multileveled hierarchy. You pass arguments to the base constructor by specifying them as arguments to base. If no base clause is present, then the base class’s default constructor is called automatically.
Name hiding in Inheritance
It is possible for a derived class to define a member that has the same name as a member in its base class. When this happens, the member in the base class is hidden within the derived class. While this is not technically an error in C#, the compiler will issue a warning message. This warning alerts you to the fact that a name is being hidden.
using System;
 
namespace inheritance_Examples
{
    class A
    {
        public int _a, _b;
        public A(int a, int b)
        {
            _a = a;
            _b = b;
        }
 
        public void Show()
        {
            Console.WriteLine("a :" + _a + "\n b:" + _b);
        }
    }
 
    class B:A
    {
        public int _c;
        public B(int a,int b,int c): base(a,b)
        {
            _c = c;
        }
 
        // This method will be hided as with same name in the base class meth
        public void Show()
        {
            Console.WriteLine("a :" + _a + "\n b:" + _b);
        }
    }
 
    class Program
    {
        static void Main()
        {
            B obj = new B(5,6,7);
            obj.Show();
 
            Console.ReadLine();
        }
    }
}

In the above program it will call the base class Show() method with below warning. As both base class and derived class has same method name, in derived class it will hide the Show () method.
Code
Description
File
CS0108
'B.Show()' hides inherited member 'A.Show()'. Use the new keyword if hiding was intended.
E:\inheritance Examples\inheritance Examples\Program.cs

If your intent is to hide a base class member, then to prevent this warning, the derived class member must be preceded by the “new” keyword. Understand that this use of new is separate and distinct from its use when creating an object instance.
using System;
 
namespace inheritance_Examples
{
   class BaseClass
    {
        public void BaseMethod()
        {
            Console.WriteLine("Base Method");
        }
    }
 
    class DerivedClass:BaseClass
    {
        public void DerivedMethod()
        {
            Console.WriteLine("Derived Method");
        }
    }
 
    class Program
    {
        static void Main()
        {
            BaseClass bc = new BaseClass();
            bc.BaseMethod();
            // With bc object you will get only
            // BaseMethod
 
            DerivedClass dc = new DerivedClass();
            dc.BaseMethod();
            dc.DerivedMethod();
            //With dc object you will get both 
            // BaseMethod and DerivedMethod 
 
            BaseClass bcObj = new BaseClass();
            DerivedClass dcObj = new DerivedClass();
            bcObj = dcObj;
            bcObj.BaseMethod();
           // bcObj.DerivedMethod();  //Error
 
            BaseClass obj = new DerivedClass();
            obj.BaseMethod();
            //bcObj.DerivedMethod();  // Error
 
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS1061
'BaseClass' does not contain a definition for 'DerivedMethod' and no accessible extension method 'DerivedMethod' accepting a first argument of type 'BaseClass' could be found (are you missing a using directive or an assembly reference?)
E:\inheritance Examples\inheritance Examples\Program.cs

Use of New Keyword in Inheritance
using System;
 
namespace inheritance_Examples
{
   class BaseClass
    {
        public void BaseMethod()
        {
            Console.WriteLine("Base Method");
        }
 
        internal void DerivedMethod()
        {
            Console.WriteLine("DerivedMethod - Base Method");
        }
    }
 
    class DerivedClass:BaseClass
    {
        public new void DerivedMethod()
        {
            Console.WriteLine("Derived Method");
        }
    }
 
    class Program
    {
        static void Main()
        {
            BaseClass bc = new BaseClass();
            bc.BaseMethod();
            // With bc object you will get only
            // BaseMethod
 
            DerivedClass dc = new DerivedClass();
            dc.BaseMethod();
            dc.DerivedMethod();
            //With dc object you will get both 
            // BaseMethod and DerivedMethod 
 
            BaseClass bcObj = new BaseClass();
            DerivedClass dcObj = new DerivedClass();
            bcObj = dcObj;
            bcObj.BaseMethod();
            bcObj.DerivedMethod();
 
            BaseClass obj = new DerivedClass();
            obj.BaseMethod();
            bcObj.DerivedMethod();
 
            Console.ReadLine();
        }
    }
}

using System;
 
namespace inheritance_Examples
{
   class BaseClass
    {
        public void Method1()
        {
            Console.WriteLine("Base Method1");
        }
 
        public void Method2()
        {
            Console.WriteLine("Base Method 2");
        }
    }
 
    class DerivedClass:BaseClass
    {
        public new void Method2()
        {
            Console.WriteLine("Derived Method2");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass();
            dc.Method1();
            dc.Method2();
            
 
            Console.ReadLine();
        }
    }
}

In the above as we used the “new” keyword in the derived class it hides base class Method2 and points to the derived class Method2. Same is true for the instance members. See the below example where we used “new” keyword to hide the base class implementation and “base” keyword to unhide the base class implementation.
using System;
 
namespace inheritance_Examples
{
    class A
    {
        public int i = 0;
    }
    class B : A
    {
        new int i; // this i hides the i in A 
        public B(int a, int b)
        {
            base.i = a; // this uncovers the i in A   
            i = b; // i in B 
        }
        public void Show()
        {    // This displays the i in A.    
            Console.WriteLine("i in base class: " + base.i);    // This displays the i in B.    
            Console.WriteLine("i in derived class: " + i);
        }
    }
    class Program
    {
        static void Main()
        {
            B ob = new B(1, 2);
            ob.Show();
 
            Console.ReadLine();
        }
    }
}

See the below example where we used virtual, override and new key word.
using System;
 
namespace inheritance_Examples
{
    class BaseClass
    {
        public virtual void Method1()
        {
            Console.WriteLine("Base Method1");
        }
 
        public virtual void Method2()
        {
            Console.WriteLine("Base Method 2");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public override void Method1()
        {
            Console.WriteLine("Derived Method1");
        }
 
        public new void Method2()
        {
            Console.WriteLine("Derived Method2");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass();
            dc.Method1();
            dc.Method2();
 
 
            Console.ReadLine();
        }
    }
}

As we used virtual keyword with Method1 in base class and override the method in derived class, it hides the Method1 in derived class and as we used the new keyword with Method2 in derived class it hides the base class Method2.

There is a second form of base that acts somewhat like this, except that it always refers to the base class of the derived class in which it is used. This usage has the following general form:
base.member
Here, member can be either a method or an instance variable. This form of base is most applicable to situations in which member names of a derived class hide members by the same name in the base class.

using System;
 
namespace inheritance_Examples
{
    class Super
    {
        public void Method()
        {
            Console.WriteLine("Called Super Class Method");
        }
    }
    class BaseClass:Super
    {
        public virtual void Method1()
        {
            Console.WriteLine("Base Method1");
        }
 
        public virtual void Method2()
        {
            Console.WriteLine("Base Method 2");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public override void Method1()
        {
            Console.WriteLine("Derived Method1");
        }
 
        public new void Method2()
        {
            Console.WriteLine("Derived Method2");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass();
            dc.Method();
            dc.Method1();
            dc.Method2();
 
 
            Console.ReadLine();
        }
    }
}


Behaviour of constructors in Inheritance
When a derived class object is created, whose constructor is executed first? The one in the derived class or the one defined by the base class?
For example, given a derived class called B and a base class called A, is A’s constructor called before B’s, or vice versa? The answer is that in a class hierarchy, constructors are called in order of derivation, from base class to derived class. Furthermore, this order is the same whether or not base is used. If base is not used, then the default (parameter less) constructor of each base class will be executed.
using System;
 
namespace inheritance_Examples
{
    class Super
    {
        public Super()
        {
            Console.WriteLine("Called Super Class Constructor");
        }
    }
    class BaseClass:Super
    {
        public BaseClass()
        {
            Console.WriteLine("Base Class Constructor");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Class Constructor");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass();
            Console.ReadLine();
        }
    }
}

If derived class constructor contains few arguments, still it follow the same hierarchy. See the below code where we passed two integer argument in the derived class constructor. And the out put is same as before.
using System;
 
namespace inheritance_Examples
{
    class Super
    {
        public Super()
        {
            Console.WriteLine("Called Super Class Constructor");
        }
    }
    class BaseClass:Super
    {
        public BaseClass()
        {
            Console.WriteLine("Base Class Constructor");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public DerivedClass(int a, int b)
        {
            Console.WriteLine("Derived Class Constructor");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass(4,4);
            Console.ReadLine();
        }
    }
}
 
If you will modify the code a little bit by placing input arguments into base class constructor then it will through an error.
using System;
 
namespace inheritance_Examples
{
    class Super
    {
        public Super()
        {
            Console.WriteLine("Called Super Class Constructor");
        }
    }
    class BaseClass:Super
    {
        public BaseClass(int a, int b)
        {
            Console.WriteLine("Base Class Constructor");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Class Constructor");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass(4,4);
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS1729
'DerivedClass' does not contain a constructor that takes 2 arguments
E:\inheritance Examples\inheritance Examples\Program.cs
CS7036
There is no argument given that corresponds to the required formal parameter 'a' of 'BaseClass.BaseClass(int, int)'
E:\inheritance Examples\inheritance Examples\Program.cs

Now change code a little bit. Remove the constructor from the super class and check the output.
using System;
 
namespace inheritance_Examples
{
    class Super
    {
        
    }
    class BaseClass:Super
    {
        public BaseClass()
        {
            Console.WriteLine("Base Class Constructor");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Class Constructor");
        }
    }
 
    class Program
    {
        static void Main()
        {
            DerivedClass dc = new DerivedClass();
            Console.ReadLine();
        }
    }
}

As super class does not contain any constructor the CLR will create a default construct for it at runtime and application runs smoothly.
Now if our application contains both parameterised and default constructor then how it will behave. Look into the below code.
using System;
 
namespace inheritance_Examples
{
    class Super
    {
        public Super()
        {
            Console.WriteLine("Super Class Constructor With No- Parameters");
        }
 
        public Super(int a)
        {
            Console.WriteLine("Base Class Constructor With 1- Parameters");
        }
    }
    class BaseClass:Super
    {
        public BaseClass()
        {
            Console.WriteLine("Base Class Constructor With No- Parameters");
        }
 
        public BaseClass(int a, int b)
        {
            Console.WriteLine("Base Class Constructor With 2- Parameters");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Class Constructor With No- Parameters");
        }
 
        public DerivedClass(int a, int b,int c)
        {
            Console.WriteLine("Derived Class Constructor With 3- Parameters");
        }
    }
 
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Output for -- DerivedClass dc = new DerivedClass();");
            DerivedClass dc = new DerivedClass();
 
            Console.WriteLine();
 
            Console.WriteLine("Output for -- DerivedClass dc = new DerivedClass(1,2,3);");
            DerivedClass dc1 = new DerivedClass(1, 2, 3);
            Console.ReadLine();
        }
    }
}

In the above code when we called with no parameters it calls all the default constructors. But when we are passing three arguments in the derived class it calls default constructor of super class and base class as with three arguments we do not have any constructor in the respective classes.
If you want to call the base class constructor then you can pass base class constructor reference to the derived class as follows and look in to the output.
using System;
 
namespace inheritance_Examples
{
    class Super
    {
        public Super()
        {
            Console.WriteLine("Super Class Constructor With No- Parameters");
        }
 
        public Super(int a)
        {
            Console.WriteLine("Base Class Constructor With 1- Parameters");
        }
    }
    class BaseClass:Super
    {
        public BaseClass()
        {
            Console.WriteLine("Base Class Constructor With No- Parameters");
        }
 
        public BaseClass(int a, int b)
        {
            Console.WriteLine("Base Class Constructor With 2- Parameters");
        }
    }
 
    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Class Constructor With No- Parameters");
        }
 
        public DerivedClass(int a, int b,int c):base(a,b)
        {
            Console.WriteLine("Derived Class Constructor With 3- Parameters");
        }
    }
 
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Output for -- DerivedClass dc = new DerivedClass();");
            DerivedClass dc = new DerivedClass();
 
            Console.WriteLine();
 
            Console.WriteLine("Output for -- DerivedClass dc = new DerivedClass(1,2,3);");
            DerivedClass dc1 = new DerivedClass(1, 2, 3);
            Console.ReadLine();
        }
    }
}

A reference variable for one class type cannot normally refer to an object of another class type. See the below code:
using System;
 
namespace inheritance_Examples
{
    class X {
        int a;
        public X(int i)
        {
            a = i;
        }
    }
    class Y {
        int a;
        public Y(int i)
        {
            a = i;
        }
    }
 
    class Program
    {
        static void Main()
        {
            X x = new X(10);
            X x2;
            Y y = new Y(5);
            x2 = x; // OK, both of same type   
            x2 = y; // Error, not of same type 
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS0029
Cannot implicitly convert type 'inheritance_Examples.Y' to 'inheritance_Examples.X'
E:\inheritance Examples\inheritance Examples\Program.cs

But when Y class is derived from X class we can assign the reference. See the below code:
using System;
 
namespace inheritance_Examples
{
    class X
    {
        public int a;
        public X(int i)
        {
            a = i;
        }
    }
    class Y:X
    {
        public int b;
        public Y(int i, int j) : base(j)
        {
            b = i;
        }
 
    }
 
    class Program
    {
        static void Main()
        {
            X x = new X(10);
            X x2;
            Y y = new Y(5, 6);
            x2 = x; // OK, both of same type    
            Console.WriteLine("x2.a: " + x2.a);
            x2 = y; // OK because Y is derived from X    
            Console.WriteLine("x2.a: " + x2.a);
 
            // X references know only about X members    
            x2.a = 19; // OK //    
           // x2.b = 27; // Error, X doesn't have a b member 
 
            Console.ReadLine();
        }
    }
}

A reference variable of a base class can be assigned a reference to an object of any class derived from that base class. This is legal because an instance of a derived type encapsulates an instance of the base type. Thus, a base class reference can refer to it.
What will happen when the virtual keyword is used with a method without implementation?

class A
{
    
public virtual void Show();
}

OUTPUT

Error 1 'ConsoleApplication.A.Show()' must declare a body because it is not marked abstract, extern, or partial

What will happen when a method is used without implementation?
class A
{
    
public void Show();
}

OUTPUT

Error 1 'ConsoleApplication.A.Show()' must declare a body because it is not marked abstract, extern, or partial

What will be the output of the C# .NET code snippet given below in which the base class method is overridden by a derived class using the override keyword?

class Program
{
    
static void Main(string[] args)
    {
        
A obj = new B();
        obj.Show();
        
Console.ReadLine();
    }
}
class A
{
    
public virtual void Show()
    {
        
Console.WriteLine("A.Show()");
    }
}
class B : A
{
    
public override void Show()
    {
        
Console.WriteLine("B.Show()");
    }
}

OUTPUT

B.Show()

What will be the output of the C# .NET code snippet given below Where the base class method is overridden by a derived class using the new keyword?

class Program
{
    
static void Main(string[] args)
    {
        
A obj = new B();
        obj.Show();
        
Console.ReadLine();
    }
}
class A
{
    
public virtual void Show()
    {
        
Console.WriteLine("A.Show()");
    }
}
class B : A
{
    
public new void Show()
    {
        
Console.WriteLine("B.Show()");
    }
}

OUTPUT

A.Show()

What will be the output of the C# .NET code snippet given below?

class Program
{
    
static void Main(string[] args)
    {
        
A obj = new B();
        obj.Show();
        
Console.ReadLine();
    }
}
class A
{
    
public virtual void Show()
    {
        
Console.WriteLine("A.Show()");
    }
}
class B : A
{
    
public void Show()
    {
        
Console.WriteLine("B.Show()");
    }
}

OUTPUT

Warning 1 'ConsoleApplication.B.Show()' hides inherited member 'ConsoleApplication.A.Show()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

Output:

A.Show()


What happen when the abstract method is used with a non-abstract class?

class A
{
    
public abstract void Show()
    {
        
Console.WriteLine("A.Show()");
    }
}

OUTPUT

Error 1 'ConsoleApplication.A.Show()' cannot declare a body because it is marked abstract
Error 2 'ConsoleApplication.A.Show()' is abstract but it is contained in non-abstract class 'ConsoleApplication.A'


What will be the output of the C# .NET code snippet given below?

class Program
{
    
static void Main(string[] args)
    {
        
C c = new C();
        
A a = new A();
        a = c;
        a.Show();
        c.Show();
        
Console.ReadLine();
    }
}
class A
{
    
public virtual void Show()
    {
        
Console.WriteLine("A.Show()");
    }     
}
class B : A
{
    
public new void Show()
    {
        
Console.WriteLine("B.Show()");
    }
}
class C : B
{
    
public new void Show()
    {
        
Console.WriteLine("C.Show()");
    }
}

OUTPUT

A.Show()
C.Show()

What will be the output of the C# .NET code snippet given below?
class Program
{
    
static void Main(string[] args)
    {
        
C c = new C();
        
A a = new A();
        a = c;
        a.Show();
        c.Show();
        
Console.ReadLine();
    }
}
class A
{
    
public virtual void Show()
    {
        
Console.WriteLine("A.Show()");
    }    
}
class B : A
{
    
public override void Show()
    {
        
Console.WriteLine("B.Show()");
    }
}
class C : B
{
    
public new void Show()
    {
        
Console.WriteLine("C.Show()");
    }
}

OUTPUT

B.Show()
C.Show()


What will be the output of the C# .NET code snippet given below?
class Program
{
    
static void Main(string[] args)
    {
        
C c = new C();
        
A a = new A();
        a = c;
        a.Show();
        c.Show();
        
Console.ReadLine();
    }
}
class A
{
    
public virtual void Show()
    {
        
Console.WriteLine("A.Show()");
    }     
}
class B : A
{
    
public override void Show()
    {
        
Console.WriteLine("B.Show()");
    }
}
class C : B
{
    
public override void Show()
    {
        
Console.WriteLine("C.Show()");
    }
}

OUTPUT

C.Show()
C.Show()

What will be the output of the C# .NET code snippet given below?
class Program
{
    
static void Main(string[] args)
    {
        
B b = new B(10);
        
Console.ReadLine();
    }
}
class A
{
    
int i;
    
public A(int j)
    {
        i = j;
        
Console.WriteLine("Base");
    }
}
class B : A
{
    
public B(int j)
    {
        
Console.WriteLine("Derived");
    }
}

OUTPUT

Error 1 'ConsoleApplication.A' does not contain a constructor that takes 0 arguments

What will be the output of the C# .NET code snippet given below?
class Program
{
    
static void Main(string[] args)
    {
        
B b = new B(10);
        
Console.ReadLine();
    }
}
class A
{
    
int i;
    
public A(int j)
    {
        i = j;
        
Console.WriteLine("Base");
    }
}
class B : A
{
    
public B(int j)
        : 
base(j)
    {
        
Console.WriteLine("Derived");
    }
}

OUTPUT

Base
Derived
Virtual Methods in Inheritance
A virtual method is a method that is declared as virtual in a base class. The defining characteristic of a virtual method is that it can be redefined in one or more derived classes. Thus, each derived class can have its own version of a virtual method. Virtual methods are interesting because of what happens when one is called through a base class reference. In this situation, C# determines which version of the method to call based upon the type of the object referred to by the reference—and this determination is made at runtime. Thus, when different objects are referred to, different versions of the virtual method are executed. In other words, it is the type of the object being referred to (not the type of the reference) that determines which version of the virtual method will be executed. Therefore, if a base class contains a virtual method and classes are derived from that base class, then when different types of objects are referred to through a base class reference, different versions of the virtual method can be executed.
You declare a method as virtual inside a base class by preceding its declaration with the keyword virtual. When a virtual method is redefined by a derived class, the override modifier is used. Thus, the process of redefining a virtual method inside a derived class is called method overriding. When overriding a method, the name, return type, and signature of the overriding method must be the same as the virtual method that is being overridden. Also, a virtual method cannot be specified as static or abstract . Method overriding forms the basis for one of C#’s most powerful concepts: dynamic method dispatch. Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at runtime, rather than compile time. Dynamic method dispatch is important because this is how C# implements runtime polymorphism. Here is an example that illustrates virtual methods and overriding:
using System;

namespace inheritance_Examples
{
    class Base
    {
        public virtual void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }

    class Derived1:Base
    {
        public override void Show()
        {
            Console.WriteLine("Derived 1 class Method is Called");
        }
    }

    class Derived2:Derived1
    {
        public override void Show()
        {
            Console.WriteLine("Derived 2 class Method is Called");
        }
    }
    class Program
    {
        static void Main()
        {
            Base baseObj = new Base();
            Derived1 derived1Obj = new Derived1();
            Derived2 derived2Obj = new Derived2();

            Base baseRef;
            baseRef = baseObj;
            baseRef.Show();

            baseRef = derived1Obj;
            baseRef.Show();

            baseRef = derived2Obj;
            baseRef.Show();

            Console.ReadLine();
        }
    }
}

This program creates a base class called Base and two derived classes, called Derived1 and Derived2. Base declares a method called Who( ), and the derived classes override it. Inside the Main( ) method, objects of type Base, Derived1, and Derived2 are declared. Also, a reference of type Base, called baseRef, is declared. The program then assigns a reference to each type of object to baseRef and uses that reference to call Show( ). As the output shows, the version of Show( ) executed is determined by the type of object being referred to at the time of the call, not by the class type of baseRef.
It is not necessary to override a virtual method. If a derived class does not provide its own version of a virtual method, then the one in the base class is used. For example:
using System;

namespace inheritance_Examples
{
    class Base
    {
        public virtual void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }

    class Derived1:Base
    {
        
    }

    class Derived2:Derived1
    {
        public override void Show()
        {
            Console.WriteLine("Derived 2 class Method is Called");
        }
    }
    class Program
    {
        static void Main()
        {
            Base baseObj = new Base();
            Derived1 derived1Obj = new Derived1();
            Derived2 derived2Obj = new Derived2();

            Base baseRef;
            baseRef = baseObj;
            baseRef.Show();

            baseRef = derived1Obj;
            baseRef.Show();

            baseRef = derived2Obj;
            baseRef.Show();

            Console.ReadLine();
        }
    }
}

In the above example Derived class does not overrides the Show Method. AS it is derived from Base class it will inherit the Base class Show method. See the output.
In the case of a multilevel hierarchy, if a derived class does not override a virtual method, then, while moving up the hierarchy, the first override of the method that is encountered is the one executed. For example:
using System;

namespace inheritance_Examples
{
    class Base
    {
        public virtual void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }

    class Derived1:Base
    {
        
    }

    class Derived2:Derived1
    {
        public override void Show()
        {
            Console.WriteLine("Derived 2 class Method is Called");
        }
    }

    class Derived3:Derived2
    {

    }
    class Program
    {
        static void Main()
        {
            Base baseObj = new Base();
            Derived1 derived1Obj = new Derived1();
            Derived2 derived2Obj = new Derived2();
            Derived3 derived3Obj = new Derived3();

            Base baseRef;
            baseRef = baseObj;
            baseRef.Show();

            baseRef = derived1Obj;
            baseRef.Show();

            baseRef = derived2Obj;
            baseRef.Show();

            baseRef = derived3Obj;
            baseRef.Show();


            Console.ReadLine();
        }
    }
}


Overridden methods allow C# to support runtime polymorphism. Polymorphism is essential to object-oriented programming for one reason: It allows a general class to specify methods that will be common to all of its derivatives, while allowing derived classes to define the specific implementation of some or all of those methods. Overridden methods are another way that C# implements the “one interface, multiple methods” aspect of polymorphism.
Part of the key to applying polymorphism successfully is understanding that the base classes and derived classes form a hierarchy that moves from lesser to greater specialization. Used correctly, the base class provides all elements that a derived class can use directly. Through virtual methods, it also defines those methods that the derived class can implement on its own. This allows the derived class flexibility, yet still enforces a consistent interface. Thus, by combining inheritance with overridden methods, a base class can define the general form of the methods that will be used by all of its derived classes.
Abstract Classes
Sometimes you will want to create a base class that defines only a generalized form that will be shared by all of its derived classes, leaving it to each derived class to fill in the details. Such a class determines the nature of the methods that the derived classes must implement, but does not, itself, provide an implementation of one or more of these methods. One way this situation can occur is when a base class is unable to create a meaningful implementation for a method. C#’s solution to this is the abstract method.
using System;

namespace inheritance_Examples
{
    abstract class Base
    {
        public void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }

        public abstract void Add();
    }
    class Derived2 : Base
    {
        public override void Add()
        {
            Console.WriteLine("Add Method is called form Derived2 Class");
        }
    }
    
    class Program
    {
        static void Main()
        {
            Derived2 d2Obj = new Derived2();
            d2Obj.Add();
            d2Obj.Show();
            Console.ReadLine();
        }
    }
}

An abstract method is created by specifying the abstract type modifier. An abstract method contains no body and is, therefore, not implemented by the base class. Thus, a derived class must override it—it cannot simply use the version defined in the base class.
·      An abstract method is automatically virtual, and there is no need to use the virtual modifier. In fact, it is an error to use virtual and abstract together.
using System;

namespace inheritance_Examples
{
    abstract class Base
    {
        public void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }

        public virtual abstract void Add();
    }
    class Derived2 : Base
    {
        public override void Add()
        {
            Console.WriteLine("Add Method is called form Derived2 Class");
        }
    }
    
    class Program
    {
        static void Main()
        {
            Derived2 d2Obj = new Derived2();
            d2Obj.Add();
            d2Obj.Show();
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS0503
The abstract method 'Base.Add()' cannot be marked virtual
E:\inheritance Examples\inheritance Examples\Program.cs

·      The abstract modifier can be used only on instance methods. It cannot be applied to static methods.
using System;

namespace inheritance_Examples
{
    abstract class Base
    {
        public void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }

        public static abstract void Add();
    }
    class Derived2 : Base
    {
        public override void Add()
        {
            Console.WriteLine("Add Method is called form Derived2 Class");
        }
    }
    
    class Program
    {
        static void Main()
        {
            Derived2 d2Obj = new Derived2();
            d2Obj.Add();
            d2Obj.Show();
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS0112
A static member 'Base.Add()' cannot be marked as override, virtual, or abstract
E:\inheritance Examples\inheritance Examples\Program.cs

·      Properties and indexers can also be abstract.
·      A class that contains one or more abstract methods must also be declared as abstract by preceding its class declaration with the abstract specifier.
using System;

namespace inheritance_Examples
{
    abstract class Base
    {
        public void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }

        public abstract void Add();
        public abstract void Devide();
    }
    abstract class Derived1 : Base
    {
        public override void Add()
        {
            Console.WriteLine("Add Method is called form Derived1 Class");
        }
    }

    class Derived2 : Derived1
    {
        public override void Devide()
        {
            Console.WriteLine("Devide Method is called form Derived2 Class");
        }
    }

    class Program
    {
        static void Main()
        {
            Derived2 d2Obj = new Derived2();
            d2Obj.Add();
            d2Obj.Devide();
            d2Obj.Show();
            Console.ReadLine();
        }
    }
}

If Derived1 class is not decorated with abstract the following error will come at compile time.
Code
Description
File
CS0534
'Derived1' does not implement inherited abstract member 'Base.Devide()'
E:\inheritance Examples\inheritance Examples\Program.cs


·      Since an abstract class does not define a complete implementation, there can be no objects of an abstract class. Thus, attempting to create an object of an abstract class by using new will Output in a compile-time error.
Code
Description
File
CS0144
Cannot create an instance of the abstract class or interface 'Derived1'
E:\inheritance Examples\inheritance Examples\Program.cs

class Program
    {
        static void Main()
        {
            Derived2 d2Obj = new Derived2();
            d2Obj.Add();
            d2Obj.Devide();
            d2Obj.Show();

            Derived1 d1Obj = new Derived1();
            Console.ReadLine();
        }
    }

·      When a derived class inherits an abstract class, it must implement all of the abstract methods in the base class. If it doesn’t, then the derived class must also be specified as abstract. Thus, the abstract attribute is inherited until such time as a complete implementation is achieved.
Sealed Classes
Sometime if you want to restrict the inheritance you can decorate that class as sealed. 
For example, you might have a class that encapsulates the initialization sequence of some specialized hardware device, such as a medical monitor. In this case, you don’t want users of your class to be able to change the way the monitor is initialized, possibly setting the device incorrectly.
Whatever the reason, in C# it is easy to prevent a class from being inherited by using the keyword sealed. To prevent a class from being inherited, precede its declaration with sealed.
using System;

namespace inheritance_Examples
{
    sealed class Base
    {
        public void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }

    class Derived3:Base
    {

    }
    class Program
    {
        static void Main()
        {
           
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS0509
'Derived3': cannot derive from sealed type 'Base'
E:\inheritance Examples\inheritance Examples\Program.cs

It is illegal to declare a class as both abstract and sealed because an abstract class is incomplete by itself and relies upon its derived classes to provide complete implementations.
using System;

namespace inheritance_Examples
{
    sealed class Base
    {
        public virtual void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }

    class Derived3
    {

    }
    class Program
    {
        static void Main()
        {
           
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS0549
'Base.Show()' is a new virtual member in sealed class 'Base'
E:\inheritance Examples\inheritance Examples\Program.cs

sealed can also be used on virtual methods to prevent further overrides.
using System;

namespace inheritance_Examples
{
    class Base
    {
        public virtual void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }
    class Derived2 : Base
    {
       sealed public override void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }
    class Derived3:Derived2
    {
        public override void Show()
        {
            Console.WriteLine("Base class Method is Called");
        }
    }
    class Program
    {
        static void Main()
        {
           
            Console.ReadLine();
        }
    }
}

Code
Description
File
CS0239
'Derived3.Show()': cannot override inherited member 'Derived2.Show()' because it is sealed
E:\inheritance Examples\inheritance Examples\Program.cs


No comments:

Post a Comment