Sono ancora lontani anni dal cogliere appieno la distinzione tra una classe astratta e un'interfaccia. Ogni volta che penso di avere un controllo sui concetti di base, vado a cercare su stackexchange e sono indietro di due passi. Ma alcuni pensieri sull'argomento e la domanda sui PO:
Per prima cosa:
Ci sono due spiegazioni comuni di un'interfaccia:
-
Un'interfaccia è una lista di metodi e proprietà che qualsiasi classe può implementare, e implementando un'interfaccia, una classe garantisce quei metodi (e le loro firme) e quelle proprietà (e i loro tipi) saranno disponibili quando " interfacciare "con quella classe o un oggetto di quella classe. Un'interfaccia è un contratto.
-
Le interfacce sono classi astratte che non / non possono fare nulla. Sono utili perché puoi implementarne più di uno, a differenza di quelli delle classi genitore medie. Ad esempio, potrei essere un oggetto di classe BananaBread ed ereditare da BaseBread, ma ciò non significa che non sia in grado di implementare sia le interfacce IWithNuts che le interfacce ITastesYummy. Potrei anche implementare l'interfaccia IDoesTheDishes, perché non sono solo pane, sai?
Ci sono due spiegazioni comuni di una classe astratta:
-
Una classe astratta è, sai, la cosa non ciò che la cosa può fare. È come l'essenza, non proprio una cosa reale. Aspetta, questo ti aiuterà. Una barca è una classe astratta, ma un Playboy Yacht sexy sarebbe una sottoclasse di BaseBoat.
-
Ho letto un libro su classi astratte e forse dovresti leggere quel libro, perché probabilmente non lo capisci e lo farai male se non hai letto quel libro.
A proposito, il libro Citers sembra sempre impressionante, anche se mi allontano ancora confuso.
Secondo:
Su SO, qualcuno ha chiesto una versione più semplice di questa domanda, il classico, "perché utilizzare le interfacce? Qual è la differenza? Cosa mi manca?" E una risposta ha utilizzato un pilota dell'aeronautica come un semplice esempio. Non è stato sufficiente, ma ha suscitato alcuni grandi commenti, uno dei quali menzionava l'interfaccia IFlyable con metodi come takeOff, pilotEject, ecc. E questo mi ha davvero fatto da esempio del mondo reale del perché le interfacce non sono solo utili, ma cruciale. Un'interfaccia rende un oggetto / classe intuitivo, o almeno dà la sensazione che sia. Un'interfaccia non è a vantaggio dell'oggetto o dei dati, ma per qualcosa che deve interagire con quell'oggetto. I classici esempi di ereditarietà di Fruit- > Apple- > Fuji o Shape- > Triangle- > Equilateral sono un grande modello per la comprensione tassonomica di un dato oggetto in base ai suoi discendenti. Informa il consumatore e i processori in merito alle sue qualità generali, ai suoi comportamenti, se l'oggetto è un gruppo di cose, snellirà il sistema se lo metti nel posto sbagliato, o descrive dati sensoriali, un connettore a un data store specifico, o dati finanziari necessari per rendere i salari.
Un oggetto Piano specifico può o non può avere un metodo per un atterraggio di emergenza, ma io sarò incazzato se presumo la sua emergenzaLand come ogni altro oggetto volabile solo per svegliarmi coperto in DumbPlane e apprendere che gli sviluppatori è andato con quickLand perché pensavano che fosse tutto uguale. Proprio come sarei frustrato se ogni produttore di viti avesse la propria interpretazione di possente o se il mio TV non avesse il pulsante di aumento del volume sopra il pulsante di diminuzione del volume.
Le classi astratte sono il modello che stabilisce ciò che qualsiasi oggetto discendente deve avere per qualificare quella classe. Se non hai tutte le qualità di un'anatra, non importa se hai implementato l'interfaccia IQuack, sei solo un pinguino strano. Le interfacce sono le cose che hanno senso anche quando non puoi essere sicuro di nient'altro. Jeff Goldblum e Starbuck erano entrambi in grado di volare astronavi aliene perché l'interfaccia era affidabile in modo simile.
Terzo:
Sono d'accordo con il tuo collega, perché a volte hai bisogno di applicare determinati metodi sin dall'inizio. Se si sta creando un ORM di record attivo, è necessario un metodo di salvataggio. Questo non dipende dalla sottoclasse che può essere istanziata. E se l'interfaccia ICRUD è abbastanza portatile da non essere accoppiato esclusivamente alla classe astratta, può essere implementata da altre classi per renderle affidabili e intuitive per chiunque abbia già familiarità con una delle classi discendenti di quella classe astratta.
D'altra parte, c'è stato un ottimo esempio prima di quando non si è passati a legare un'interfaccia alla classe astratta, perché non tutti i tipi di lista implementeranno (o dovrebbero) implementare un'interfaccia di coda. Hai detto che questo scenario si verifica per metà tempo, il che significa che tu e il tuo collega avete entrambi metà del tempo sbagliato, e quindi la cosa migliore da fare è discutere, discutere, considerare, e se risultano essere giusti, riconoscere e accettare l'accoppiamento . Ma non diventare uno sviluppatore che segue una filosofia anche quando non è la migliore per il lavoro a portata di mano.