Abstract Classes in C# are classes, intended only to be a base class of other classes. Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class. Reference
With other words – what does this mean? An abstract class with abstract methods is built only, with the idea of the methods being overriden by the classes tha inherit from it. Let’s imagine an abstract class Car with 2 abstract methods – StartEngine() and Stop Engine():
1 2 3 4 5 |
public abstract class Car { public abstract string StartEngine(); public abstract string StopEngine(); } |
A class SmallCar inherits from Car. Thus, we try to write class SmallCar : Car
, but the SmallCar is colored with red line below. Anyhow, pressing Ctrl + Dot automatically builds the missing implementation of the abstract classes:
Which is somehow beautiful. And saves a lot of time. 🙂 Furthermore, imagine that we have built another class, BitTruck, which also inherits from Car:
1 2 3 4 5 6 7 8 9 10 11 12 |
class BigTruck : Car { public override string StartEngine() { return "Big Truck starts the engine"; } public override string StopEngine() { return "Big Truck stops the engine"; } } |
Then, if one wants to start both the BigTruck and the SmallCar, which are added to a list of Cars, this is a possible working code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
namespace tuesday1203 { using System; using System.Collections.Generic; class Startup { static void Main() { List<Car> myCars = new List<Car>(); myCars.Add(new BigTruck()); myCars.Add(new SmallCar()); foreach (Car car in myCars) { Console.WriteLine(car.StartEngine()); } } } } |
And this is how the console looks like:
Pretty nice, eh? Using the inherited classes in a list of the type that they are inheriting. Going further. Imagine that you are in need to use the abstract class with a method, which is the same for all the classes that inherit from it. What do you do? Pretty much, the following is quite enough:
1 2 3 4 5 6 7 8 9 |
public abstract class Car { public abstract string StartEngine(); public abstract string StopEngine(); public string YearsNeededToDrive() { return "You should be 18 years to drive it!"; } } |
The string method “YearsNeededToDrive” would return the same result from any class, which inherits from car. Without implementation, of course, because the method is not an abstract one:
1 2 3 4 5 6 7 8 9 |
List<Car> myCars = new List<Car>(); myCars.Add(new BigTruck()); myCars.Add(new SmallCar()); foreach (Car car in myCars) { Console.WriteLine(car.StartEngine()); Console.WriteLine(car.YearsNeededToDrive()); } |
And this is what is produced:
1 |
Not bad, eh? :) Now, let's talk a bit about constructors. This is how the constructor of the base class looks like: |
1 2 3 4 5 6 |
public int year { get; set; } protected Car(int yearOfProduction) { this.year = yearOfProduction; } |
It is not inherited by the classes, that inherit the base class, because constructors are not to be inherited. Thus, an implementation is needed in both classes:
1 2 3 |
public SmallCar(int yearOfProduction) : base(yearOfProduction) { } |
This is how it is called, now with the parameter yearOfProduction:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
static void Main() { List<Car> myCars = new List<Car>(); myCars.Add(new BigTruck(2011)); myCars.Add(new SmallCar(2010)); foreach (Car car in myCars) { Console.WriteLine(car.StartEngine()); Console.WriteLine(car.YearsNeededToDrive()); Console.WriteLine(car.ProducedIn()); } } |
And this is the result:
The code from the article is in GitHub here.