C# Constructor Inheritance allows derived classes to inherit and utilize the constructors of their base classes. This feature provides a more efficient way to reuse code, reduce redundancy, and promote maintainability of the codebase. In this article, we will explore the syntax, and provide real-world scenario code examples. By the way, did you know that we offer a unique online course that boosts your C# career? Check it out here!
Why?
In object-oriented programming, inheritance is the mechanism that enables a class to inherit properties and behaviors of another class. Constructors are special methods that are invoked during the creation of an object, and they are used to initialize the fields of the object. When a class is derived from another class, it is common to want to utilize the constructors of the base class to initialize the fields inherited from the base class. C# enables this by allowing derived classes to utilize the constructors of their base classes.
By using constructor inheritance, developers can avoid duplicating code for initializing the same fields in both the base class and the derived class. This not only reduces the amount of code that needs to be written but also improves the maintainability of the codebase and reduces the likelihood of bugs due to duplicate code.
Syntax
The syntax is quite simple. After defining the constructor in a derived class, add the base
keyword followed by the parameter list of the constructor in the base class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) { Name = name; Age = age; } } class Employee : Person { public int EmployeeId { get; set; } public Employee(string name, int age, int employeeId) : base(name, age) { EmployeeId = employeeId; } } |
In the example above, the Person
class has a constructor that takes two parameters name and age and initializes the Name
and Age
properties. The Employee
class is derived from the Person
class and declares a constructor that takes three parameters name
, age
, and employeeId
. The Employee
constructor uses the base keyword to call the constructor of the Person
class with the name
and age
parameters.
Examples
The following are some examples that demonstrate the use of constructor inheritance.
Example 1: A Shape Class Hierarchy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class Shape { public int X { get; set; } public int Y { get; set; } public Shape(int x, int y) { X = x; Y = y; } } class Circle : Shape { public int Radius { get; set; } public Circle(int x, int y, int radius) : base(x, y) { Radius = radius; } } class Rectangle : Shape { public int Width { get; set; } public int Height { get; set; } public Rectangle(int x, int y, int width, int height) : base(x, y) { Width = width; Height = height; } } |
In the example above, the Shape
class has a constructor that takes two parameters x
and y
and initializes the X
and Y
properties. The Circle
and Rectangle
classes are derived from the Shape
class and declare their own constructors that call the constructor of the Shape
class using the base keyword. The Circle
class adds a Radius
property and the Rectangle
class adds Width
and Height
properties.
Example 2: A Base Database Connection Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
class DbConnection { private string _connectionString; private TimeSpan _timeout; public DbConnection(string connectionString) { if (string.IsNullOrEmpty(connectionString)) throw new ArgumentException("Connection string cannot be null or empty."); _connectionString = connectionString; } public virtual void Open() { // Open database connection } public virtual void Close() { // Close database connection } //... } class SqlConnection : DbConnection { public SqlConnection(string connectionString) : base(connectionString) { // SqlConnection specific initialization } public override void Open() { // Open SQL Server database connection } public override void Close() { // Close SQL Server database connection } //... } class OracleConnection : DbConnection { public OracleConnection(string connectionString) : base(connectionString) { // OracleConnection specific initialization } public override void Open() { // Open Oracle database connection } public override void Close() { // Close Oracle database connection } //... } |
In the example above, the DbConnection
class is a base class for database connections and has a constructor that takes a connectionString
parameter. The SqlConnection
class and OracleConnection
class are derived from the DbConnection
class and declare their own constructors that call the constructor of the DbConnection
class using the base keyword. The SqlConnection
class and OracleConnection
class also override the Open
and Close
methods to provide database-specific implementations.
Conclusion
Calling base constructors promotes code reuse, reduces code redundancy and helps developers to produce maintainable code that is easier to understand and extend. If you want to skyrocket your C# career, check out our powerful ASP.NET full-stack web development course that also covers test-driven development.