Classe abstrata e interface C#

Resumo : neste tutorial, você aprenderá quando usar uma classe abstrata e quando usar uma interface e as diferenças entre uma classe abstrata e uma interface.

Escolhendo entre uma classe abstrata e uma interface

Em C#, uma classe abstrata é semelhante a uma interface . No entanto, a classe abstrata e a interface servem a propósitos diferentes. Portanto, é importante saber quando usar uma classe abstrata e quando usar uma interface.

Geralmente, quando você deseja modelar o relacionamento é-um e compartilhar uma implementação comum com todas as subclasses, você usa uma classe abstrata.

Mas quando você deseja criar um contrato ao qual outras classes devem aderir, você usa uma interface.

O exemplo a seguir demonstra como usar a classe abstrata Shape que possui o método Display() compartilhado por todas as suas subclasses:

abstract class Shape
{
    public abstract double GetArea();
    public abstract double GetPerimeter();

    public void Display()
    {
        Console.WriteLine($"Area: {GetArea():F2}, Perimeter: {GetPerimeter():F2}");
    }
}

class Rectangle : Shape
{
    readonly double length;
    readonly double width;

    public Rectangle(double length, double width)
    {
        this.length = length;
        this.width = width;
    }

    public override double GetArea()
    {
        return length * width;
    }

    public override double GetPerimeter()
    {
        return 2 * (length + width);
    }
}

class Circle : Shape
{
    readonly double radius;

    public Circle(double radius)
    {
        this.radius = radius;
    }

    public override double GetArea()
    {
        return Math.PI * radius * radius;
    }

    public override double GetPerimeter()
    {
        return 2 * Math.PI * radius;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var shapes = new List<Shape>()
        {
            new Rectangle(5, 10),
            new Circle(3)
        };

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

    }
}Linguagem de código:  C#  ( cs )

Saída:

Area: 50.00, Perimeter: 30.00
Area: 28.27, Perimeter: 18.85Linguagem de código:  CSS  ( css )

Neste exemplo, a Shapeclasse é uma classe abstrata que define dois métodos abstratos GetAreae GetPerimeter. Qualquer classe que herda da classe Shape precisa implementar esses métodos.

A Shapeclasse também possui um método concreto Displayque exibe a área e o perímetro de uma forma. Todas as subclasses da Shapeclasse compartilharão o mesmo Displaymétodo.

As classes Rectangle e Circle estendem a classe Shape. Ambas as classes compartilham a mesma implementação de Displaymétodo, mas cada uma fornece sua própria implementação GetAreae GetPerimetermétodos.

O exemplo a seguir demonstra como usar uma interface como contrato:

interface ILogger
{
    void Log(string message);
}

class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}

class FileLogger : ILogger
{
    private readonly string filePath;

    public FileLogger(string filePath)
    {
        this.filePath = filePath;
    }

    public void Log(string message)
    {
        using StreamWriter writer = new StreamWriter(filePath, true);
        writer.WriteLine(message);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ILogger logger;

        if (args.Length > 0 && args[0] == "file")
        {
            logger = new FileLogger("log.txt");
        }
        else
        {
            logger = new ConsoleLogger();
        }

        logger.Log("Starting application...");

        // ... 

        logger.Log("Application stopped.");
    }
}
Linguagem de código:  C#  ( cs )

Neste exemplo, definimos a ILoggerinterface que possui um único método Log. O Logmétodo utiliza uma string que representa a mensagem a ser registrada.

As classes ConsoleLoggere FileLoggerimplementam a ILoggerinterface e fornecem suas próprias implementações do Logmétodo.

No Mainmétodo, criamos uma instância ConsoleLoggerou FileLoggercom base no argumento da linha de comando.

Se o argumento for "file", criamos um FileLoggerobjeto. Caso contrário, criamos um ConsoleLoggerobjeto.

Independentemente de FileLoggera ConsoleLoggerinstância ter sido criada, chamamos o Logmétodo para registrar algumas mensagens

Como ambas FileLoggeras ConsoleLoggerclasses implementam a mesma interface, podemos alternar facilmente entre elas em tempo de execução.

Classe abstrata vs. Interface

A tabela a seguir ilustra as diferenças entre classes abstratas e interfaces:

Aulas abstratas Interfaces
Implementação compartilhada Definir um contrato
Só pode herdar de uma única classe base Pode implementar qualquer número de interfaces
Código de implementação irrestrito Código de implementação limitado
Pode ter propriedades automáticas Sem propriedades automáticas

Resumo

  • Use uma classe abstrata para modelar um relacionamento é-um e compartilhe uma implementação comum com todas as subclasses.
  • Use uma interface para representar um contrato ao qual outras classes devem aderir.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *