Risipa de key_press | Programare

Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Risipa de key_press | Programare - Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Interfete in .Net

    Scriam in articolul despre mostenire (inheritance) ca mostenirea unei clase foarte importanta in C#. Dar, un altfel de mostenire, cea a interfetelor, are o putere mult mai mare.

    O interfata defineste  un set de metode, proprietati, evenimente, indexatori care vor fi implementate de o clasa. Atentie, interfetele NU implementeaza, ele sunt abstracte si doar isi descriu  membrii. Interfata precizeaza CE trebuie facut, dar NU si CUM trebuie facut.

   Sintactic, interfetele sunt asematoare cu clasele abstract, cu mentiunea ca nici o metoda nu poate avea corp. Se foloseste cuvantul cheie interface.

interface  nume {
   tip nume-metoda (param);
   tip nume-metoda(param);
}

tip – tipul de date returnat de metoda,

param – signatura metodei, lista de parametri – numarul si tipul lor.

Toti membri declarati in interfata, sunt public in mod implicit.

    public interface Interfata
    {
        void Metoda1();
        void Metoda2();
    }

  Dupa definirea interfetei, o clasa o va putea implementa folosind aceeasi sintaxa ca la mostenirea unei clase de baza, prin specificarea numelui interfetei dupa numele clasei, separate de “:”.

Exemplu : selectam in Visual Studio numele interfetei si la click dreapta vom implementa interfata :

implementare implicita

Codul, avand continutul metodelor modificat :

  
    //clasa A implementeaza interfata Interfata
    class A : Interfata {

        #region Interfata Members

        public void Metoda1()
        {
            Console.WriteLine("Metoda1");
        }

        public void Metoda2()
        {
            Console.WriteLine("Metoda2");
        }

        #endregion
    }

   La crearea unei interfete, ca restrictii avem faptul ca nu putem defini un constructor, un destructor, constante. Mai mult, o interfata nu poate mosteni o clasa sau o structura.

   O interfata poate fi implementata de un numar infinit de clase.

   O clasa poate implementa un numar infinit de interfete. Cand o clasa implementeaza o interfata, va trebui sa implementeze toate metodele acesteia, care sunt de tip public. Specificatorii de acces nu sunt permisi. O clasa nu poate alege pentru implementare doar anumite metode.

Exemplu:

  public interface I1
    {
        void Metoda1();
        void Metoda2();
    }

    public interface I2
    {
        void Metoda3();
        void Metoda4();
    }
  class A : I1, I2
    {

        #region I1 Members

        public void Metoda1()
        {
            throw new NotImplementedException();
        }

        public void Metoda2()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region I2 Members

        public void Metoda3()
        {
            throw new NotImplementedException();
        }

        public void Metoda4()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    In cazul in care o clasa implementeaza mai multe interfete, numele acestora vor fi separate prin “,”. Este intalnita situatia cand o clasa va mosteni o clasa de baza si va implementa una sau mai multe interfete – numele clasei de baza trebuie sa fie primul in lista separata prin virgule.

Mostenirea interfetelor

    O interfata poate mosteni o alta interfata. Sintaxa este comuna cu cea folosita la mostenirea claselelor. Daca o clasa mostenteste o interfata care mosteneste o alta interfata, clasa va trebui sa contina implementari pentru toti membri definiti pe lantul de mostenire al interfetei.

Exemplu :

  
    //interfata accesibila in tot programul
    public interface A
    {
        void Metoda1();
        void Metoda2();
    }
    //interfata B va include metoda1 si metoda2 plus metoda3
    public interface B : A
    {
        void Metoda3();
    }
    //clasa Test va trebui sa implementeze toate mteodele din A si B
    class Test : B
    {

        #region B Members

        public void Metoda3()
        {
            Console.WriteLine("Metoda3");
        }

        #endregion

        #region A Members

        public void Metoda1()
        {
            Console.WriteLine("Metoda1");
        }

        public void Metoda2()
        {
            Console.WriteLine("Metoda2");
        }

        #endregion
    }

    Si in cadrul mostenirii interfetelor, poate aparea situatia cand un membru al interfetei derivate are aceeasi signatura cu membrul cu acelasi nume din interfata de baza. Situatia va genera un mesaj de atentionare si va fi rezolvata prin folosirea operatorului  new, daca se doreste ca membrul din interfata de baza sa fie ascuns. (la fel ca la mostenirea claselor).

    O implementare explicita inseamna specificarea numelui complet, prefixand numele membrului cu numele interfetei. O implementare explicita este necesara pentru eliminarea ambiguitatii in cazul a doua interfete cu metode care au acelasi nume si aceasi signatura. Un alt motiv pentru implementarea explicita ar fi ca metoda respectiva nu va fi vizibila pentru codul din afara clasei.

Exemplu :

Pastram interfetele definite mai sus. Acum, selectam in Visual Studio numele interfetei si la click dreapta vom implementa interfata in mod explicit

interfata_explicit

Doar la implementarea metodei2 vom aduce modificari, pentru a fi vizibila in afara clasei.

  class Test : B
    {
        #region B Members

        void B.Metoda3()
        {
            Console.WriteLine("Metoda3.Implementare explicita");
        }

        #endregion

        #region A Members

        void A.Metoda1()
        {
            Console.WriteLine("Metoda1.Implementare explicita");
        }

        //am adaugat public si am sters implementarea explicita
        public void Metoda2()
        {
            Console.WriteLine("Metoda2");
        }

        #endregion

    }
 
     //metodele implementate explicit, nu vor fi vizibile
     Test t = new Test();
     t.Metoda2();

    In .Net, printre cele mai folosite interfete se numara IDisposable, (folosita pentru eliberarea spatiului de memorie), IComparable (folosita pentru sortare), IConvertible (pentru convertirea la tipuri de baza), etc.

    O interfata este o constructie pur abstracta. Pentru un programator, nu doar in C#, lucrul cu interfetele trebuie stapanit foarte bine.

Category: Uncategorized
  • Adi says:

    Interesant tutorialul. Am citit si altele, insa nu am reusit sa inteleg f bine cand anume chiar avem nevoie sa folosim o interfata. Cu alte cuvinte, exista situatii in care este nevoie (obligatoriu) de implementarea unei interfete?

    February 8, 2014 at 10:48 am
    • zeltera says:

      Interfetele sunt notiuni putin mai avansate de programare si au un rol foarte important in implementarea unor solutii putin mai complicate (design patterns). Dupa ce o sa scrii vre-o 2 ani cod o sa intelegi utilitatea lor. Atat timp cat nu intelegi la ce folosesc si nu simti nevoia de a le folosi, uita de ele!

      O sa incerc in viitor sa scriu cateva articole despre interfete. Stai pe aproape.

      February 8, 2014 at 3:33 pm
  • Alex says:

    Salut, respect enorm si felicitari pentru ceea ce faceti aici, pot sa spun ca dupa ce am citit teoria si nici n-am ajuns la practica cu cartea si am facut tutorialele de pe acest site am inteles perfect cum functioneaza , obiectele , clasele , mostenirea , polimorfismul etc. Ca sa fiu on topic in legatura cu aceasta sectiune, vad ca mai sus ati scris ca in mod normal ajungem sa intelegem utilitatea interfetelor dupa vreo 2 ani de scris de cod … acum polemica mea este urmatoarea: Daca le invat din prima n-ar fi mai usor pentru lizibitatea codului ? Am citit in carte teoria despre aceste interfete si observ ca sunt o practica foarte buna pentru a “descurca” mai bine codul intr-un program. De ce considerati ca n-ar fi mai bine sa le utilizam de la inceput, din cauza ca sunt mai greu de implementat in program, sau din cauza ca e sintaxa mai complexa ? … precizez ca inca n-am inteles practic cum functioneaza dar vreau sa stiu pentru ca eu as vrea sa-mi formez de la inceput un anumit tipar in programare care pe viitor, o data cu practica sa intre in reflex si sa-mi fie mai usor in crearea aplicatiilor

    December 13, 2014 at 11:34 pm
    • zeltera says:

      Daca ai inteles despre ce e vorba si cum se folosesc, evident, poti sa le folosesti. Ideea e ca interfetele sunt concepte putin mai greu de inteles tocmai pentru ca sunt legate de tehnici mai avansate de programare (sabloane – patterns). In acelasi timp, nu te pierde in structuri complexe pentru programe simple. interfetele sunt facute sa te ajute sa simplifici codul, sa implementezi mostenire (multipla) etc. Daca nu ai nevoie de asa ceva in structura codului pe care il scrii, nu le folosi.

      December 14, 2014 at 2:30 am

Your email address will not be published. Required fields are marked *

*