C# > Object-Oriented Programming (OOP) > Abstraction > Abstract Methods

Abstract Class with Abstract Methods: Shape Example

This snippet demonstrates abstraction using an abstract class Shape with abstract methods CalculateArea and Display. Derived classes (Circle and Rectangle) must implement these methods, providing concrete implementations specific to each shape.

Defining the Abstract Shape Class

This declares an abstract class named Shape. It includes a property Name and two abstract methods: CalculateArea and Display. An abstract method has no implementation in the abstract class; it is a placeholder that must be implemented by derived classes. The abstract class also contains a constructor to initialize the Name property. Abstract classes cannot be instantiated directly.

public abstract class Shape
{
    public string Name { get; set; }

    public Shape(string name)
    {
        Name = name;
    }

    public abstract double CalculateArea();
    public abstract void Display();
}

Implementing the Circle Class

The Circle class inherits from the Shape class. It provides concrete implementations for the abstract methods CalculateArea and Display. The CalculateArea method calculates the area of the circle based on its radius. The Display method prints the shape's name and its calculated area to the console. Note the use of the override keyword, which is essential when implementing abstract methods from a base class.

public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(string name, double radius) : base(name)
    {
        Radius = radius;
    }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }

    public override void Display()
    {
        Console.WriteLine($"Shape: {Name}, Area: {CalculateArea()}");
    }
}

Implementing the Rectangle Class

The Rectangle class, similar to Circle, inherits from Shape and provides concrete implementations for CalculateArea and Display. The CalculateArea method calculates the area of the rectangle based on its width and height. The Display method outputs the shape's name and area.

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public Rectangle(string name, double width, double height) : base(name)
    {
        Width = width;
        Height = height;
    }

    public override double CalculateArea()
    {
        return Width * Height;
    }

    public override void Display()
    {
        Console.WriteLine($"Shape: {Name}, Area: {CalculateArea()}");
    }
}

Using the Shapes

This example demonstrates how to create instances of the derived classes (Circle and Rectangle) and call their implemented methods. Notice that you can't create an instance of Shape directly because it's an abstract class. The Display method leverages the overridden implementations within each shape class.

public class Example
{
    public static void Main(string[] args)
    {
        Circle circle = new Circle("My Circle", 5);
        Rectangle rectangle = new Rectangle("My Rectangle", 4, 6);

        circle.Display();       
        rectangle.Display();
    }
}

Concepts Behind the Snippet

Abstraction focuses on hiding complex implementation details and exposing only essential information to the user. Abstract classes and methods are a key part of achieving abstraction in OOP. They define a common interface for related classes while allowing each class to provide its specific implementation.

Real-Life Use Case

Consider a drawing application. You might have abstract classes for different types of graphical objects (e.g., shapes, lines, images). Each type of object would have abstract methods for drawing itself on the screen. The specific implementation of the drawing method would differ depending on the object type, but the interface (the abstract method) would remain consistent.

Best Practices

  • Use abstract classes when you want to define a common interface but force derived classes to provide specific implementations.
  • Avoid creating abstract classes with no abstract methods. If a class is not intended to be instantiated, consider making it a static class instead (if applicable).
  • Favor interfaces over abstract classes when you need multiple inheritance or when you want to define a contract without providing any default implementation.

Interview Tip

Be prepared to explain the difference between abstract classes and interfaces. Abstract classes can have state (fields) and provide partial implementations, while interfaces are purely contracts that define a set of methods. Also, be ready to discuss the 'is-a' relationship (inheritance) versus the 'can-do' relationship (interface implementation).

When to Use Them

Abstract methods are useful when you have a hierarchy of classes and you want to ensure that certain methods are implemented in all derived classes. It enforces a certain structure for all subclasses.

Memory Footprint

Abstract classes themselves don't directly consume memory because you can't instantiate them. However, derived classes will consume memory based on their fields and methods. There's generally no significant memory overhead associated with using abstract methods.

Alternatives

Interfaces provide an alternative way to achieve abstraction. You can define an interface with method signatures that classes must implement. Interfaces offer more flexibility in terms of multiple inheritance but cannot contain implementation details.

Pros

  • Enforces a consistent interface for related classes.
  • Promotes code reusability through inheritance.
  • Hides implementation details from the client code.

Cons

  • Can increase code complexity if overused.
  • Derived classes are tightly coupled to the abstract class.
  • Single inheritance restriction (a class can only inherit from one abstract class).

FAQ

  • Can I create an instance of an abstract class?

    No, you cannot create an instance of an abstract class directly. Abstract classes are designed to be base classes for other classes and must be inherited from to be used.
  • What happens if a derived class doesn't implement all abstract methods?

    If a derived class does not implement all abstract methods from the abstract base class, the derived class must also be declared as abstract.
  • Can an abstract class have constructors?

    Yes, an abstract class can have constructors. Although you cannot instantiate the abstract class directly, the constructors are called when a derived class is instantiated. Constructors are often used to initialize the state of the abstract class.