Sobes.tech
Junior

În ce cazuri și în ce scopuri folosim interfețele în C#?

sobes.tech AI

Răspuns de la AI

Interfețele în C# sunt utilizate pentru atingerea următoarelor scopuri:

  1. Definirea unui contract: Interfața definește un set de membri (metode, proprietăți, evenimente, indexatori) pe care o clasă sau structură care implementează această interfață trebuie să îi implementeze. Acest lucru asigură coerența în comportamentul diferitelor tipuri.

    // Definirea interfeței
    public interface IDrawable
    {
        void Draw();
        int LineThickness { get; set; }
    }
    
    // Clasă care implementează interfața
    public class Circle : IDrawable
    {
        public int LineThickness { get; set; }
    
        public void Draw()
        {
            // Logica de desenare a unui cerc
        }
    }
    
  2. Polimorfism: Utilizarea interfețelor permite lucrul cu obiecte de tipuri diferite printr-un tip comun de interfață. Acest lucru se realizează deoarece orice referință la un obiect care implementează interfața poate fi convertită în acel tip de interfață.

    // Metodă care lucrează cu orice obiect care implementează IDrawable
    public void Render(IDrawable item)
    {
        item.Draw(); // Se apelează implementarea concretă a metodei Draw
    }
    
    // Utilizare:
    IDrawable circle = new Circle();
    Render(circle); // Se va apela implementarea Draw() din clasa Circle
    
  3. Moștenire multiplă: C# nu suportă moștenirea multiplă a claselor, dar permite ca o clasă sau structură să implementeze mai multe interfețe. Acest lucru permite unui tip să aibă comportamente definite în diferite "contracte".

    public interface ISaveable
    {
        void Save();
    }
    
    public interface ILoadable
    {
        void Load();
    }
    
    // Clasă care implementează mai multe interfețe
    public class ConfigurationManager : ISaveable, ILoadable
    {
        public void Save()
        {
            // Logica de salvare
        }
    
        public void Load()
        {
            // Logica de încărcare
        }
    }
    
  4. Decuplare (Decoupling): Utilizarea interfețelor permite reducerea dependenței între componente. În loc să depindă de o clasă concretă, un component poate depinde de o interfață. Acest lucru facilitează înlocuirea implementărilor și testarea.

    public interface ILogger
    {
        void LogMessage(string message);
    }
    
    public class FileLogger : ILogger
    {
        public void LogMessage(string message)
        {
            // Logica de scriere în fișier
        }
    }
    
    public class DatabaseLogger : ILogger
    {
        public void LogMessage(string message)
        {
            // Logica de scriere în bază de date
        }
    }
    
    public class ProcessingEngine
    {
        private readonly ILogger _logger;
    
        // Dependență de interfață, nu de o implementare concretă
        public ProcessingEngine(ILogger logger)
        {
            _logger = logger;
        }
    
        public void ProcessData()
        {
            // ...
            _logger.LogMessage("Datele au fost procesate.");
        }
    }
    
  5. Extensibilitate: Interfețele permit adăugarea ușoară a noilor implementări ale comportamentelor existente fără a modifica codul care utilizează această interfață.

  6. Documentație și auto-documentare: O interfață bine denumită, cu comentarii la membrii săi, servește ca o formă de documentație, descriind comportamentul așteptat de la obiectele care implementează această interfață.