Inheritance, in C#, is the ability to create a class that inherits attributes and behaviors from an existing class. The newly created class is the derived (or child) class and the existing class is the base (or parent) class.
Inheritance is one of the key features of object-oriented programming. The benefits of inheritance are part of the reason why structural programming can be replaced with object-oriented programming.
Inheritance in C# is designed at both implementation and at interface level. Implementation inheritance involves code from one class that is reused in another, while interface inheritance implies the inheritance of only the signatures of functions from one type to another.
C# does not support multiple inheritance, which means a class can derive from one base class only, although a class can be derived from one or more interfaces. Due to the transitive nature of inheritance, a derived class inherits all the members of its ancestors.
For example, classes, Car and Bus can be derived from a base class, Vehicle, through inheritance because both Car and Bus are types of Vehicle.
The main features of inheritance include:
All the members of the base class except those with private accessibility can be accessed in the derived class.
All the members of the base class are inherited from the base class except constructors and destructors.
Unlike in C++, the virtual methods in a derived class need to use the modifier "override" to override an inherited member.
To hide an inherited member with the same name and signature in the derived class, the "new" modifier can be used.
To prevent direct instantiation of a class, the "abstract" modifier can be used.
To prevent further derivation of a base class, it can be declared using "sealed" modifier.
Inheritance provides the following benefits:
It enables the construction of a hierarchy of related classes that can reuse, extend and alter the behaviors defined in the existing classes.
It allows code reuse, reducing time and effort in coding and testing.
It helps improve modularity and performance by dividing large pieces of code into smaller, more manageable, pieces.
It forms the means to achieve polymorphism, which allows an object to represent more than one type.