Until now, you have learned about class and objects. In this chapter, you will expand your knowledge to an advanced level.
In this chapter, we are going to make subclasses of a class. A subclass is also called a derived class and the class from which it is derived (parent class) is called superclass or base class.
We also know that a subclass can use members of its parent class.
In C#, we use :
to make a subclass.
In this example, ChildClass is derived from a class ParentClass.
Let's take an example.
using System;
class Student //base class
{
public string name;
public string GetName()
{
return this.name;
}
public void SetName(string name)
{
this.name = name;
}
public void PrintAbout()
{
Console.WriteLine("I am a student");
}
}
class Undergraduate: Student
{
public void UndergradPrint()
{
Console.WriteLine("I am an Undergraduate");
}
}
class Test
{
static void Main(string[] args)
{
Student s = new Student();
Undergraduate u = new Undergraduate();
s.PrintAbout();
u.PrintAbout();
u.UndergradPrint();
}
}
class Undergraduate: Student
→ Undergraduate is the name of a class which is a subclass or derived class of the Student class.
As stated above, a child class can access all members of its parent class (if they are not private), you can see that the object of the Undergraduate class is accessing the method of its parent class - u.PrintAbout()
.
However, a parent class can't access members of its child class. For example, s.UndergradPrint()
will give an error.
Before going further, let's learn more about the protected modifier.
C# Protected
Any protected member of a class (variable or function) can be accessed within that class or its subclass. It cannot be accessed outside that.
Let's take an example.
using System;
class Student //base class
{
protected string name;
public void SetName(string name)
{
this.name = name;
}
}
class Undergraduate: Student
{
public void PrintName()
{
Console.WriteLine(name);
}
}
class Test
{
static void Main(string[] args)
{
Undergraduate u = new Undergraduate();
u.SetName("xyz");
u.PrintName();
}
}
In the Student class, we made the variable name protected. So, it can be accessed directly within its subclass Undergraduate. And we did the same. We accessed the variable name directly in the method PrintName of its subclass.
We first created an object u of the subclass Undergraduate. Since an object of a subclass can access any of the members of its parent class, so u called the method SetName of its parent class with a string parameter "xyz". This string got assigned to the variable name thus making the value of name as "xyz" for the object u.
Then, u called the function PrintName which printed the value of name i.e., xyz.
C# Constructor of Subclass
We can have constructors for both base and derived class to initialize their respective members. The constructor of the derived class can call the constructor of the base class, but the inverse is not true. Let's see how.
Calling Base Class Constructor Having No Parameter
If the base class constructor has no parameter, then it will be automatically whenever the derived class constructor will be called, even if we do not explicitly call it.
Look at the following to understand it.
using System;
class A
{
public A()
{
Console.WriteLine("Constructor of A");
}
}
class B: A
{
public B()
{
Console.WriteLine("Constructor of B");
}
}
class Test
{
static void Main(string[] args)
{
B b = new B();
}
}
While calling the constructor of any class, the compiler first automatically calls the constructor of its parent class. This is the reason that while calling the constructor of class B, the compiler first called the constructor of its parent class A and then the constructor of B. Thus when the constructor of B was called, the compiler first called the constructor of A thus printing "Constructor of A" and after that "Constructor of B".
Let's see another example where the constructor of the parent class gets automatically called first.
using System;
class A
{
public A()
{
Console.WriteLine("Constructor of A");
}
}
class B: A
{
public B()
{
Console.WriteLine("Constructor of B");
}
}
class C: B
{
public C()
{
Console.WriteLine("Constructor of C");
}
}
class Test
{
static void Main(string[] args)
{
Console.WriteLine("Creating object of A :");
A a = new A();
Console.WriteLine("Creating object of B :");
B b = new B();
Console.WriteLine("Creating object of C :");
C c = new C();
}
}
Here, when the object of A was created, its constructor was called, printing "Constructor of A".
When the object of B was created, the compiler first called the constructor of its parent class A, printing "Constructor of A" and after that printing "Constructor of B".
Similarly, when the constructor of C was called, first the constructor of its parent class B was called. On calling the constructor of B, the constructor of A got called, printing "Constructor of A" followed by "Constructor of B". At last, "Constructor of C" got printed.
Calling Parameterized Base Class Constructor
Unlike parent class constructors having no parameter, parameterized parent class constructors are not called automatically while calling its child class constructor.
To call a parent class constructor having some parameter form the constructor of its subclass, we have to use the base
keyword.
base
keyword can be used to access any member of base class. Let's take an example on this first.
using System;
class A
{
public void Method()
{
Console.WriteLine("Inside A");
}
}
class B: A
{
public B()
{
base.Method();
}
}
class Test
{
static void Main(string[] args)
{
B b = new B();
}
}
In this example, we accessed the method of parent class using the base
keyword - base.Method()
.
We can also access the constructor of a base class using the base
keyword. Suppose we need to pass a variable x to the constructor of class A from class B. We can do so by writing public B(): base(x)
. Let's take an example.
using System;
class A
{
public A(int l)
{
Console.WriteLine($"Length : {l}");
}
}
class B: A
{
public B() : base(10)
{
Console.WriteLine("This is constructor of B");
}
}
class Test
{
static void Main(string[] args)
{
B b = new B();
}
}
In this example, we passed 10 to the constructor of A (parent class) from the class B (child class).
Let's take one more example.
using System;
class Rectangle
{
public int length;
public int breadth;
public Rectangle(int l, int b)
{
length = l;
breadth = b;
}
public int GetArea()
{
return length*breadth;
}
public int GetPerimeter()
{
return 2*(length+breadth);
}
}
class Square: Rectangle
{
public Square(int a): base(a, a)
{
}
}
class Test
{
static void Main(string[] args)
{
Square s = new Square(2);
int area, p;
area = s.GetArea();
p = s.GetPerimeter();
Console.WriteLine($"Area : {area}");
Console.WriteLine($"Perimeter : {p}");
}
}
We know that a square is also a rectangle with the same length and breath. This is what we did in the constructor of Square.
We created an object s of class Square and passed 2 at the time of creating it. So, this 2 will be passed to the constructor of class Square. Hence, the value of a will be 2.
In the constructor of Square, constructor of its superclass Rectangle is being called with the value of a as 2, thus making the value of both its length and breadth equal to a i.e. 2.
Finally, in the Main method, we used the object s of the class Square to call two functions of its parent class Rectangle.
C# sealed
In C#, sealed
keyword is used to restrict a class from being derived. It means that if we use sealed
with a class, we won't be able to create any subclass of it.
We can also use sealed
keyword with methods to prevent them for being overridden which we will see in next chapters.
Let's look at an example of using sealed
with a class.
using System;
sealed class A
{
}
class B: A
{
}
class Test
{
static void Main(string[] args)
{
}
}
In this example, we tried to make a subclass of sealed class A and that's why we got the error.