PWI Software Documentation Help

Base Classes vs Interfaces

Base Classes

A base class is a regular class that other classes can be derived from. This is also known as class inheritance. When a class inherits from a base class, it gains all the properties and methods that the base class has. For example:

public abstract class Mammal { public string Name { get; set; } public void Eat() { Console.WriteLine("Eating..."); } public abstract void Speak(); } public class Dog : Mammal { public override void Speak() { Console.WriteLine("Barking..."); } }

Here, Dog is a subclass of Mammal and inherits the Name property and Eat() method from Mammal. We can instantiate Dog and use these features like so:

var myDog = new Dog(); myDog.Name = "Fido"; myDog.Eat(); // prints "Eating..." myDog.Speak(); // prints "Barking..."

Did you notice the abstract method Speak() in Mammal? We can use the abstract keyword when we want to force an inheriting class to define its own implementation. Use this when a method needs to exist in inheriting classes, but you do not want to define the exact implementation in the base class. In the inheriting class, we use the override keyword to signify that we are replacing the functionality of the base class. Note that in order to use the abstract keyword in a class, you also need to declare the entire class as abstract.

The reason you'd choose to use a base class is when you want to define shared behaviors or properties that are common to all subclasses. Non-abstract public, protected, and internal methods or properties of the base class can be accessed by any subclass, as if they were declared in the subclass itself.

Interfaces

An interface is like a contract. It says, "Any class that implements me must provide these properties and/or methods." Unlike base classes, interfaces do not provide any actual code or data, they only define what needs to be in the class that implements them. For example:

public interface IRunnable { void Run(); } public class Human : IRunnable { public void Run() { Console.WriteLine("Moving legs fast to run..."); } } public class Generator : IRunnable { public void Run() { Console.WriteLine("Pumping gas and creating sparks to run..."); } }

Here, Human implements the IRunnable interface, so it must provide a Run() method. We can create an instance of Human and call Run() like this:

var human = new Human(); human.Run(); // prints "Moving legs fast to run..."

Generator also implements the IRunnable interface, so it must also provide a Run() method. We can create an instance of Generator and call Run() in the same way:

var generator = new Generator(); generator.Run(); // prints "Pumping gas and creating sparks to run..."

Notice that in both cases we do not need to use the override keyword to define Run(). This is because interfaces cannot define method bodies - they can only declare that the Run() method must exist in classes that implement it.

Putting them together

Let's put the examples above together. We can rewrite the Human class to also implement the Mammal base class:

public class Human : Mammal, IRunnable { public void Run() { Console.WriteLine("Moving legs fast to run..."); } public override void Speak() { Console.WriteLine($"Hello! My name is {Name}"); } }

Remember that the Run() method does not need to use the override keyword, since the Run() method is declared in an interface. However, since the Speak() method is declared in a class, we must use the override keyword to define its behavior.

Now, Human inherits the Mammal class, and implements the IRunnable class. We can use it like this:

var human = new Human(); human.Name = "Jason"; human.Eat(); // prints "Eating..." human.Speak(); // prints "Hello! My name is Jason." human.Run(); // prints "Moving legs fast to run..."

When to use which one?

Use a base class when you have common behavior with some default implementation. Use an interface when you want to ensure that a class adheres to a certain contract, but the implementation of that contract will vary across different classes.

It is important to note that in C#, a class can inherit from multiple interfaces, but can only inherit one base class. This may affect your decision about which one you want to use.

02 February 2024