E 'possibile creare un'istanza di un'interfaccia (e.g-Map Interface)? Se è allora come?

1

Nella maggior parte del codice Java, vedo persone dichiarare oggetti Java come questo:

Map<String, String> hashMap = new HashMap<>();

invece di:

HashMap<String, String> hashMap = new HashMap<>();

Come è possibile (so che è, ma perché) creare istanze di un'interfaccia Map quando sappiamo che non possiamo creare l'istanza di un'interfaccia. Per favore, spiega. Grazie in anticipo.

    
posta vaibhav negi 28.05.2017 - 09:59
fonte

4 risposte

5

Si chiama polimorfismo:
L'istanza di una classe può essere considerata come un'istanza di quella classe, ma anche come un'istanza di ogni interfaccia implementata dalla classe, poiché deve implementare tutti i metodi dell'interfaccia. Un'interfaccia è un contratto che dice: "La classe che mi implementa offre almeno le stesse operazioni che offro".

Ogni HashMap è una mappa, ma non tutte le mappe sono una HashMap.

    
risposta data 28.05.2017 - 10:08
fonte
2

Non puoi creare un'istanza di interface , perché interface è fondamentalmente una classe astratta senza la restrizione dell'ereditarietà multipla.
E una classe astratta manca di parti della sua implementazione, oppure è esplicitamente contrassegnata come astratta per proibire l'istanza.

Ciò che puoi fare, e nel tuo esempio, è creare un'istanza di una classe derivata da (detta implementazione) detta interfaccia, e trasmetterla a qualsiasi base, sia essa un'interfaccia, una classe concreta o una classe astratta .

A meno che l'esecutore non abbia sciolto il contratto, il principio di sostituzione di Liskov si applica e funziona proprio come tu hai effettivamente istanziato il interface .

    
risposta data 28.05.2017 - 15:28
fonte
2

Java proibisce l'utilizzo di interfacce per creare oggetti , ma non impedisce loro di essere utilizzati per creare variabili .

Considera cosa sta effettivamente accadendo in questo codice:

    Map<String, String> hashMap = new HashMap<>();
  1. Una variabile di riferimento è dichiarata sullo stack con un nome "hashMap" e digita Map<String, String> .

  2. A new istanza di tipo HashMap<> viene creata su heap

  3. Alla variabile 'hashMap' è assegnato un handle di riferimento (ovvero un valore dell'indirizzo di memoria) relativo all'istanza appena creata.

Nota:

  • una variabile è un'area di memoria denominata , nello stack.
  • un oggetto è una istanza di una classe , nell'heap.
  • una variabile di riferimento è una variabile per un handle di riferimento .
  • un handle di riferimento è un numero che rappresenta la posizione di memoria di un oggetto sull'heap.

Questo è importante perché ci sono due "cose" che vengono create in memoria, una variabile di riferimento e un oggetto. Una variabile di riferimento è più di un semplice nome per un oggetto; infatti una variabile di riferimento può mantenere un handle su qualsiasi oggetto, a condizione che il tipo di oggetto sia compatibile con il tipo della variabile.

Ad esempio, tutte le classi in Java sono in definitiva derivate da Object , quindi una variabile il cui tipo è Object può fare riferimento a qualsiasi istanza di qualsiasi classe.

Tuttavia, una variabile di tipo Map<String, String> può solo fare riferimento a un'istanza di una classe che implementa l'interfaccia Map<String, String> .

In definitiva, non c'è alcun problema con la creazione di una variabile da un'interfaccia, poiché le variabili di riferimento non supportano alcun comportamento in sé (tranne che per la garbage collection). Una variabile di riferimento è un modo per un programma di tenere traccia degli oggetti allocati nell'heap e il tipo di una variabile determina le operazioni che il programma può eseguire su un oggetto di riferimento.

    
risposta data 28.05.2017 - 19:07
fonte
1
Map<String, String> hashMap = new HashMap<>();

L'affermazione precedente fa tre cose:

  1. Crea una nuova istanza di HashMap<String, String> .
  2. Crea una variabile che possa contenere un riferimento a Map<String, String> .
  3. Memorizza il riferimento dell'oggetto creato nel passaggio 1 nella variabile creata nel passaggio 2.

È importante notare che l'oggetto sottostante è ancora un HashMap<String, String> . Poiché HashMap implementa l'interfaccia Map , può essere controllata da una variabile con il tipo Map . In futuro, se avessi bisogno di cambiare l'implementazione della mappa, tutto ciò che devi fare è cambiare ciò che viene fatto nel passaggio 1.

È importante notare che il codice che viene dopo questa prima riga avrà accesso solo ai metodi definiti nell'interfaccia Map .

Ad esempio:

interface SomeInterface {
  void foo();
}
class SomeClass implements SomeInterface {
  void foo() {
    // ...
  }
  void bar() {
    // ...
  }
}
// ...
SomeInterface thing = new SomeClass();
thing.foo(); // works
this.bar(); // doesn't compile because bar() is not defined in SomeInterface
    
risposta data 28.05.2017 - 15:03
fonte

Leggi altre domande sui tag