Ok, un mio amico va avanti e indietro su cosa significa "interfaccia" nella programmazione.
Qual è la migliore descrizione di una "interfaccia".
Per me un'interfaccia è il modello di una classe, è questa la migliore definizione?
Ok, un mio amico va avanti e indietro su cosa significa "interfaccia" nella programmazione.
Qual è la migliore descrizione di una "interfaccia".
Per me un'interfaccia è il modello di una classe, è questa la migliore definizione?
Risposte:
Un'interfaccia è uno dei termini più sovraccarichi e confusi nello sviluppo.
In realtà è un concetto di astrazione e incapsulamento. Per una data "scatola", dichiara gli "input" e gli "output" di quella scatola. Nel mondo del software, questo di solito significa le operazioni che possono essere invocate sulla scatola (insieme agli argomenti) e in alcuni casi i tipi di ritorno di queste operazioni.
Quello che non fa è definire quale sia la semantica di queste operazioni, sebbene sia un luogo comune (e una pratica molto buona) documentarle in prossimità della dichiarazione (ad esempio, tramite commenti), o scegliere buone convenzioni di denominazione. Tuttavia, non ci sono garanzie che queste intenzioni vengano seguite.
Ecco un'analogia: dai un'occhiata alla tua televisione quando è spenta. La sua interfaccia sono i pulsanti che ha, i vari connettori e lo schermo. La sua semantica e il suo comportamento sono che accetta input (ad esempio, programmazione via cavo) e ha output (visualizzazione sullo schermo, suono, ecc.). Tuttavia, quando guardi una TV non collegata, stai proiettando la tua semantica attesa in un'interfaccia. Per quanto ne sai, il televisore potrebbe semplicemente esplodere quando lo colleghi alla presa di corrente. Tuttavia, in base alla sua "interfaccia" puoi presumere che non farà caffè poiché non ha una presa d'acqua.
Nella programmazione orientata agli oggetti, un'interfaccia definisce generalmente l'insieme di metodi (o messaggi) a cui potrebbe rispondere un'istanza di una classe che ha quell'interfaccia.
Ciò che aggiunge confusione è che in alcuni linguaggi, come Java, esiste un'interfaccia effettiva con la semantica specifica del linguaggio. In Java, ad esempio, è un insieme di dichiarazioni di metodo, senza implementazione, ma un'interfaccia corrisponde anche a un tipo e obbedisce a varie regole di digitazione.
In altri linguaggi, come C ++, non hai interfacce. Una classe stessa definisce i metodi, ma potresti pensare all'interfaccia della classe come alle dichiarazioni dei metodi non privati. A causa del modo in cui C ++ si compila, ottieni file di intestazione in cui potresti avere l '"interfaccia" della classe senza l'effettiva implementazione. Puoi anche imitare le interfacce Java con classi astratte con funzioni virtuali pure, ecc.
Un'interfaccia non è certamente un modello per una classe. Un progetto, per definizione, è un "piano d'azione dettagliato". Un'interfaccia non promette nulla su un'azione! La fonte della confusione è che nella maggior parte delle lingue, se si dispone di un tipo di interfaccia che definisce un insieme di metodi, la classe che lo implementa "ripete" gli stessi metodi (ma fornisce la definizione), quindi l'interfaccia sembra uno scheletro o un schema della classe.
Considera la seguente situazione:
Sei nel mezzo di una grande stanza vuota, quando uno zombi ti attacca all'improvviso.
Non hai armi.
Fortunatamente, un altro essere umano vivente è in piedi sulla soglia della stanza.
"Presto!" gli gridi. "Lanciami qualcosa con cui posso colpire lo zombi!"
Ora considera:
non hai specificato (né ti interessa) esattamente cosa sceglierà di lanciare il tuo amico;
... Ma non importa, a patto che:
È qualcosa che può essere lanciato (non può lanciarti sul divano)
È qualcosa che puoi afferrare (speriamo che non abbia lanciato uno shuriken)
È qualcosa che puoi usare per colpire il cervello degli zombi (questo esclude cuscini e simili)
Non importa se prendi una mazza da baseball o un martello -
finché implementa le tue tre condizioni, sei bravo.
Riassumendo:
Quando scrivi un'interfaccia, in pratica stai dicendo: "Ho bisogno di qualcosa che ..."
L'interfaccia è un contratto a cui dovresti conformarti o a cui devi dare, a seconda che tu sia implementatore o utente.
Non credo che "progetto" sia una buona parola da usare. Un progetto ti dice come costruire qualcosa. Un'interfaccia evita specificamente di dirti come costruire qualcosa.
Un'interfaccia definisce come puoi interagire con una classe, cioè quali metodi supporta.
Per me un'interfaccia è il modello di una classe, è questa la migliore definizione?
No. Un progetto tipicamente include gli interni. Ma un'interfaccia riguarda esclusivamente ciò che è visibile all'esterno di una classe ... o più precisamente, una famiglia di classi che implementano l'interfaccia.
L'interfaccia è costituita dalle firme dei metodi e dai valori delle costanti e anche da un "contratto comportamentale" (tipicamente informale) tra le classi che implementano l'interfaccia e altre che la utilizzano.
Nella programmazione, un'interfaccia definisce quale sarà il comportamento di un oggetto, ma non specificherà effettivamente il comportamento. È un contratto, che garantirà che una certa classe possa fare qualcosa.
Considera questo pezzo di codice C # qui:
using System;
public interface IGenerate
{
int Generate();
}
// Dependencies
public class KnownNumber : IGenerate
{
public int Generate()
{
return 5;
}
}
public class SecretNumber : IGenerate
{
public int Generate()
{
return new Random().Next(0, 10);
}
}
// What you care about
class Game
{
public Game(IGenerate generator)
{
Console.WriteLine(generator.Generate())
}
}
new Game(new SecretNumber());
new Game(new KnownNumber());
La classe Game richiede un numero segreto. Per motivi di test, si desidera iniettare quello che verrà utilizzato come numero segreto (questo principio è chiamato inversione di controllo).
La classe del gioco vuole essere "di mentalità aperta" su cosa creerà effettivamente il numero casuale, quindi chiederà al suo costruttore "qualsiasi cosa, che abbia un metodo Generate".
Innanzitutto, l'interfaccia specifica quali operazioni fornirà un oggetto. Contiene solo ciò che sembra, ma non viene fornita alcuna implementazione effettiva. Questa è solo la firma del metodo. Convenzionalmente, in C # le interfacce hanno il prefisso I. Le classi ora implementano l'interfaccia IGenerate. Ciò significa che il compilatore si assicurerà che entrambi abbiano un metodo, che restituisca un int e venga chiamato Generate
. Il gioco ora viene chiamato due oggetti diversi, ognuno dei quali implementa l'interfaccia corretta. Altre classi produrranno un errore durante la creazione del codice.
Qui ho notato l'analogia del progetto che hai usato:
Una classe è comunemente vista come un modello per un oggetto. Un'interfaccia specifica qualcosa che una classe dovrà fare, quindi si potrebbe sostenere che in realtà è solo un progetto per una classe, ma poiché una classe non ha necessariamente bisogno di un'interfaccia, direi che questa metafora si sta interrompendo. Pensa a un'interfaccia come a un contratto. La classe che "lo firma" sarà obbligata per legge (fatta rispettare dalla polizia del compilatore), per rispettare i termini e le condizioni del contratto. Ciò significa che dovrà fare ciò che è specificato nell'interfaccia.
Tutto ciò è dovuto alla natura tipizzata staticamente di alcuni linguaggi OO, come nel caso di Java o C #. In Python, invece, viene utilizzato un altro meccanismo:
import random
# Dependencies
class KnownNumber(object):
def generate(self):
return 5
class SecretNumber(object):
def generate(self):
return random.randint(0,10)
# What you care about
class SecretGame(object):
def __init__(self, number_generator):
number = number_generator.generate()
print number
In questo caso, nessuna delle classi implementa un'interfaccia. Python non si preoccupa di questo, perché la SecretGame
classe proverà semplicemente a chiamare qualunque oggetto sia passato. Se l'oggetto HA un metodo generate (), va tutto bene. In caso contrario: KAPUTT! Questo errore non verrà visualizzato in fase di compilazione, ma in fase di esecuzione, quindi probabilmente quando il programma è già distribuito e in esecuzione. C # ti avviserebbe molto prima che tu ti avvicini a questo.
Il motivo per cui viene utilizzato questo meccanismo, dichiarato ingenuamente, perché nei linguaggi OO le funzioni naturalmente non sono cittadini di prima classe. Come puoi vedere, KnownNumber
e SecretNumber
contengono SOLO le funzioni per generare un numero. Non si ha davvero bisogno delle lezioni. In Python, quindi, si potrebbe semplicemente buttarli via e scegliere le funzioni da soli:
# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())
# Functional Approach
# Dependencies
class SecretGame(object):
def __init__(self, generate):
number = generate()
print number
SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)
Un lambda è solo una funzione, che è stata dichiarata "in linea, mentre procedi". Un delegato è esattamente lo stesso in C #:
class Game
{
public Game(Func<int> generate)
{
Console.WriteLine(generate())
}
}
new Game(() => 5);
new Game(() => new Random().Next(0, 10));
Nota a margine: gli ultimi esempi non erano possibili come questo fino a Java 7. Là, le interfacce erano l'unico modo per specificare questo comportamento. Tuttavia, Java 8 ha introdotto espressioni lambda in modo che l'esempio C # possa essere convertito in Java molto facilmente ( Func<int>
diventa java.util.function.IntSupplier
e =>
diventa ->
).
Tecnicamente, descriverei un'interfaccia come un insieme di modi (metodi, proprietà, funzioni di accesso ... il vocabolario dipende dalla lingua che stai usando) per interagire con un oggetto. Se un oggetto supporta / implementa un'interfaccia, è possibile utilizzare tutti i modi specificati nell'interfaccia per interagire con questo oggetto.
Semanticamente, un'interfaccia potrebbe anche contenere convenzioni su ciò che puoi o non puoi fare (ad esempio, l'ordine in cui puoi chiamare i metodi) e su ciò che, in cambio, potresti assumere sullo stato dell'oggetto dato come hai interagito così lontano.
Personalmente vedo un'interfaccia come un modello. Se un'interfaccia contiene la definizione per i metodi foo () e bar (), allora sai che ogni classe che usa questa interfaccia ha i metodi foo () e bar ().
Consideriamo che un uomo (utente o oggetto) vuole che venga svolto del lavoro. Contatterà un intermediario (Interface) che avrà un contratto con le aziende (oggetti del mondo reale creati utilizzando classi implementate). Pochi tipi di lavori saranno definiti da lui che le aziende realizzeranno e gli daranno risultati. Ogni azienda implementerà il lavoro a modo suo, ma il risultato sarà lo stesso. In questo modo, l'utente svolgerà il proprio lavoro utilizzando un'unica interfaccia. Penso che Interface agirà come parte visibile dei sistemi con pochi comandi che saranno definiti internamente dai sottosistemi interni di implementazione.
Un'interfaccia separa le operazioni su una classe dall'implementazione all'interno. Pertanto, alcune implementazioni possono fornire molte interfacce.
La gente normalmente lo descrive come un "contratto" per ciò che deve essere disponibile nei metodi della classe.
Non è assolutamente un progetto, poiché ciò determinerebbe anche l'attuazione. Si potrebbe dire che una definizione di classe completa è un modello.
Un'interfaccia definisce cosa deve implementare una classe che eredita da essa. In questo modo, più classi possono ereditare da un'interfaccia e, grazie a tale eredità, puoi farlo
per maggiori informazioni, vedi questo http://msdn.microsoft.com/en-us/library/ms173156.aspx
Secondo me l'interfaccia ha un significato più ampio di quello comunemente associato ad essa in Java. Definirei "interfaccia" un insieme di operazioni disponibili con alcune funzionalità comuni, che consentono il controllo / monitoraggio di un modulo.
In questa definizione cerco di coprire sia le interfacce programmatiche, dove il client è un modulo, sia le interfacce umane (GUI per esempio).
Come altri hanno già detto, un'interfaccia ha sempre un contratto alle spalle, in termini di input e output. L'interfaccia non promette nulla sul "come" delle operazioni; garantisce solo alcune proprietà del risultato, dato lo stato corrente, l'operazione selezionata ed i suoi parametri.
Come sopra, i sinonimi di "contratto" e "protocollo" sono appropriati.
L'interfaccia comprende i metodi e le proprietà che ci si può aspettare di essere esposti da una classe.
Quindi, se una classe Cheetos Bag
implementa l' Chip Bag
interfaccia, dovresti aspettarti che Cheetos Bag
a si comporti esattamente come qualsiasi altra Chip Bag
. (Cioè, esponi il .attemptToOpenWithoutSpillingEverywhere()
metodo, ecc.)
Definizione convenzionale: un'interfaccia è un contratto che specifica i metodi che devono essere implementati dalla classe che lo implementa.
La definizione di interfaccia è cambiata nel tempo. Pensi che Interface abbia solo dichiarazioni di metodo? Che dire delle variabili finali statiche e delle definizioni predefinite dopo Java 5.
Le interfacce sono state introdotte in Java a causa del problema Diamond con ereditarietà multipla ed è ciò che intendono effettivamente fare.
Le interfacce sono i costrutti che sono stati creati per farla franca con il problema dell'ereditarietà multipla e possono avere metodi astratti, definizioni predefinite e variabili finali statiche.
Un confine attraverso il quale comunicano due sistemi.
Le interfacce sono il modo in cui alcuni linguaggi OO raggiungono il polimorfismo ad hoc . Il polimorfismo ad hoc è semplicemente funzioni con gli stessi nomi che operano su tipi diversi.
In breve, il problema di base che un'interfaccia sta cercando di risolvere è separare il modo in cui utilizziamo qualcosa da come viene implementato. Ma dovresti considerare l'interfaccia non è un contratto . Leggi di più qui .