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 B: Test, A
{
}
}
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 B: A
{
}
class C: B
{
}
}
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 true; return 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 C: B
{
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 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()");
}
{
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
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