Blog for Junior Developers C#/.NET

Saturday, July 13, 2024

In the previous 2 articles on inheritance and polymorphism, I tried to present you the basics of object-oriented programming, I told you that the topic of polymorphism will be further developed, because in the abstract we also deal with polymorphism. Also, this time I will touch on the topic of abstraction, this is another extremely important topic in object-oriented programming, the knowledge of which will help you find a job as a junior C#/.NET programmer. In C#, we use abstract classes and interfaces to apply abstraction. In this article I will introduce you to these issues.

what-is-abstraction-in-object-oriented-programming.jpg

What is abstraction and why do we need abstraction?


Abstraction is best understood with an example. Let's assume you have a DVD player. Everyone knows what such a DVD player looks like, that is, what such a player looks like from the outside. However, each such player has some complicated logic inside, but on the outside it only has a few buttons that are made available to users. Typically, these are the start, stop, power, etc. buttons that users use to communicate with this player. Consumers of such a player are usually not interested in what is happening inside. They are only interested in how to turn on, turn off, stop such a player, and maybe a few other functions :) And this is just abstraction. That is, we are not interested in the details of a given implementation, we are only interested in what is made available to us externally. We have some kind of contract and we know that all implementations must include given features, without informing consumers about their details.


Example in programming


If in programming we cooperate with a database, for example, we have a contract that tells us that each class should meet certain criteria. That is, to implement a function, for example, adding data to the database, deleting, editing, reading data, etc., we are not interested in a specific implementation. Let's assume that our class implements this contract and works with an MSSQL database. If the abstraction has been well designed, we are not dependent only on this one database, we can at any time change our implementation to work with another database, for example in PostgreSQL, Firebird, etc. and that is the point, we do not want to become dependent on a given database. engine, a given implementation. This makes our applications loosely coupled and more flexible and extensible. Moreover, introducing abstractions makes our code more testable. As I have already mentioned, in programming we can use abstraction through abstract classes and interfaces. We say that each object performs some tasks without revealing the implementation details.


What is an abstract class?


With abstract classes we can introduce a certain level of abstraction into our class. An abstract class is a class that was created to be a base class for other classes. Such classes as well as methods must be marked with the abstract keyword. Unable to create an abstract class object. This class can contain method declarations themselves, as well as method definitions, that is, implementations.


An example of an abstract class


In the last article on polymorphism. I showed you some inheritance hierarchy, where the base class was the Shape method. Meaning:

public class Shape
{
    public virtual void Draw()
    {
        Console.WriteLine("Draw Base");
    }
}

public class Square : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw Square");
    }
}

public class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw Triangle");
    }
}

public class Program
{
    static void Main(string[] args)
    {
        var shapes = new List<Shape>()
        {
            new Shape(),
            new Square(),
            new Triangle()
        };

        foreach (var shape in shapes)
        {
            shape.Draw();
        }
    }
}

//OUTPUT
//Draw Base
//Draw Square
//Draw Triangle


However, there are several drawbacks to this hierarchy. I mean, we have a Shape class here and we can create an instance of such a class, but does an object of this class make any sense? This class also has a Draw method, but can you draw a shape? We know how to draw a square or triangle, but how to draw a shape? Well, that's why this class should be abstract, that is, marked with abstract. So let's make some tweaks to this code.

public abstract class Shape
{
    public abstract void Draw();
}

public class Square : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw Square");
    }
}

public class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw Triangle");
    }
}

public class Program
{
    static void Main(string[] args)
    {
        var shapes = new List<Shape>()
        {
            new Shape(), //ERROR! - Cannot create an instance of the abstract class or interface 'Shape'
            new Square(),
            new Triangle()
        };

        foreach (var shape in shapes)
        {
            shape.Draw();
        }
    }
}


Thanks to the abstract keyword, the Shape class has become an abstract class, we cannot create an instance of this class and this is also what we wanted. The Draw method has also been marked with a keyword as an abstract method, the declaration of this method itself has been defined, and therefore we are sure that each derived class must implement its own implementation of this method. We override abstract methods in derived classes with the override keyword. Also, abstract methods are virtual in nature and provide polymorphic behavior, which is what the previous article was about. You must remember that abstract methods can only be created in an abstract class and written in a derived class by using override. Moreover, methods that are not abstract can also be implemented in an abstract class, in which case they must contain implementations. We can also use such classes when we want to introduce some common behavior, but we want to be sure that each derived class will define such a method.


What is an interface?


Interfaces, unlike abstract classes, enable complete separation of implementation details from shared elements. Before C# 8, interfaces could only contain method declarations, they could not contain method definitions - this definition had to be in the class implementing the interface. Since C# 8, interfaces can also contain default method definitions. Unlike classes, we use the interface keyword here. The convention is that we add the prefix I to the name, that is, in our case it could be IShape. It is also common to add the suffix able to the interface name, meaning that something is capable of something, for example IMoveable.

public interface IShape
{
    void Draw();
}



What is the difference between an abstract class and an interface?


This is a very popular, frequently asked question during job interviews for the position of junior .NET developer (more). The most important differences between an abstract class and an interface are:

  • We use the interface keyword in the interface declaration and the abstract class keyword in the abstract class.
  • A class can implement any number of interfaces and can only inherit from one abstract class.
  • Interface members cannot be marked with access attributes (it is always implicitly public), and in an abstract class they can be marked with access attributes.
  • You cannot declare fields in interfaces, but you can in an abstract class.
  • An interface cannot have a constructor, and an abstract class can implement a default constructor.


SUMMARY:


In this article, you learned another extremely important issue from the point of view of object-oriented programming. I showed you what abstraction is, what are the advantages of using abstraction, how you can implement abstraction in C#. You already know what interfaces, abstract classes, abstract methods are and you know the differences between them. Next week I will show you the 4th pillar of object-oriented programming, which is data encapsulation. See you next week.
Author of the article:
Kazimierz Szpin

KAZIMIERZ SZPIN
Software Developer C#/.NET, Freelancer. Specializes in ASP.NET Core, ASP.NET MVC, ASP.NET Web API, Blazor, WPF and Windows Forms.
Author of the blog CodeWithKazik.com

Previous article - What is Polymorphism in Object Oriented Programming?
Next article - What is Encapsulation in Object Oriented Programming?
Comments (1)
Kazimierz Szpin
KAZIMIERZ SZPIN, poniedziałek, 15 lipca 2024 11:03
What do you think about this article? I'm curious about your opinion.
Dodaj komentarz

Search engine

© Copyright 2024 CodeWithKazik.com. All rights reserved. Privacy policy.
Design by Code With Kazik