Instantiating Interfaces in C #?

4

Al momento sto leggendo / imparando le interfacce in C # e finora sono riuscito a capire come si differenzia da una classe astratta. Nel libro che sto leggendo l'autore spiega che le interfacce sono l'ultima classe astratta e che semplicemente imposta lo standard di certi metodi che avrà la classe ereditante, ma poi fornisce il seguente esempio.

static void Main(string[] args)
{
...
Circle c = new Circle("Lisa");
IPointy itPt = null;
try
{
itPt = (IPointy)c;
Console.WriteLine.(itPt.Points);
}
catch (InvalidCastException e)
{
 Console.WriteLine(e.Message);
}
...
}

La linea che mi ha assolutamente buttato fuori è il IPointy itfPt=null; ha appena dichiarato un'interfaccia? Ho pensato che le interfacce sono astratte e possono essere ereditate solo? Che tipo di stregoneria sta succedendo qui?

    
posta RealityDysfunction 07.10.2012 - 01:54
fonte

4 risposte

11

Questo esempio dimostra una prova ... cattura più di ogni altra cosa.

Anche le interfacce sono tipi ... ma espongono solo il loro contratto. Quindi questo:

IPointy itPt = new IPointy();

.. non funzionerà. Considera questo:

interface IPointy {
    void MyMethod();
}

class Pencil : IPointy {
    void MyMethod() {
    }

    void MyOtherMethod() {
    }
}

Puoi dichiarare un IPointy in questo modo:

IPointy itPt = new Pencil();

.. tuttavia, funzionerà:

itPt.MyMethod();

.. questo non funzionerà:

itPt.MyOtherMethod();

Questo perché MyMethod è parte del contratto IPointy .. MyOtherMethod non lo è .. Speriamo che questo aiuti.

EDIT: Espansione di questo per spiegare il mio commento.

L'ereditarietà di una classe rappresenta una relazione "è-a". L'implementazione di un'interfaccia rappresenta una relazione "can-do".

Si consideri:

interface ISwitchable {
    void SwitchOn();
    void SwitchOff();
}

class Light : ISwitchable {
    void SwitchOn() { }
    void SwitchOff() { }
}

class Television : ISwitchable {
    void SwitchOn() { }
    void SwitchOff() { }
}

Sia la televisione che la luce ereditano da ISwitchable .. che va bene. L'interfaccia definisce una relazione "can-do". Possono essere entrambi attivati orr di. Entrambi i seguenti blocchi di codice sono validi:

ISwitchable mySwitchableObject1 = new Light();
ISwitchable mySwitchableObject2 = new Television();

mySwitchableObject1.SwitchOn(); // calls Light's SwitchOn method
mySwitchableObject2.SwitchOn(); // calls Television's SwitchOn method
    
risposta data 07.10.2012 - 02:10
fonte
2

Puoi dichiarare le variabili digitate come interfacce: ciò non equivale a istanziarle . Una volta dichiarata una variabile del tipo di interfaccia, puoi assegnarla un oggetto di qualsiasi classe che implementa l'interfaccia.

Ad esempio, puoi dichiarare una variabile di tipo di interfaccia IDictionary<string,string> , ma non puoi istanziarla: devi scegliere una classe che implementa IDictionary<string,string> , ad esempio

IDictionary<string,string> d = new Dictionary<string,string>();

o

IDictionary<string,string> d = new SortedList<string,string>();
    
risposta data 07.10.2012 - 02:14
fonte
1

Un'interfaccia viene dichiarata usando la parola chiave interface, che quella riga di codice non contiene.

Quello che vedi è una dichiarazione di variabile, una variabile chiamata itfPt, il cui tipo è IPointy. La variabile ottiene il valore 'null', che non è un'istanza.

L'istanziazione dell'interfaccia IPointy non è possibile, puoi provare a farlo digitando itfPt = new IPointy (); ed esaminando gli errori di compilazione. Gli unici valori che possono essere assegnati a itfPt sono istanze di sottotipi concreti di IPointy e null.

    
risposta data 07.10.2012 - 02:01
fonte
1

Penso che quello che cerchi sia l'istanza dell'interfaccia e l'uso di esso. Ecco un esempio che può aiutarti:

public interface IFoo
{
    void Bar1();
    void Bar2();
}

public Class ActionableFoo : IFoo
{
    Action _bar1, _bar2;

    public ActionableFoo(Action b1, Action b2)
    {
        _bar1 = b1;
        _bar2 = b2;
    }

    public void Bar1() { if(_bar1 != null) _bar1(); }
    public void Bar2() { if(_bar2 != null) _bar2(); }
}

public void PushFoo(Action bar1, Action bar2)
{
    IFoo foo = new ActionableFoo(bar1, bar2);
    _fooStack.Push(foo);
}
    
risposta data 07.10.2012 - 02:08
fonte

Leggi altre domande sui tag