Ci sono molte ottime risposte qui, ma spesso trovo che usare ENTRAMBE le interfacce e le classi astratte sia il percorso migliore. Considera questo esempio artificioso:
Sei uno sviluppatore di software presso una banca di investimento e devi creare un sistema che inserisca ordini in un mercato. L'interfaccia coglie l'idea più generale di ciò che un sistema di negoziazione fa ,
1) Trading system places orders
2) Trading system receives acknowledgements
e può essere catturato in un'interfaccia, ITradeSystem
public interface ITradeSystem{
public void placeOrder(IOrder order);
public void ackOrder(IOrder order);
}
Ora gli ingegneri che lavorano al banco vendite e lungo altre linee di business possono iniziare a interfacciarsi con il tuo sistema per aggiungere funzionalità di posizionamento degli ordini alle loro app esistenti. E non hai ancora iniziato a costruire! Questo è il potere delle interfacce.
Quindi vai avanti e costruisci il sistema per gli operatori di borsa ; hanno sentito che il tuo sistema ha una funzione per trovare azioni a basso costo e sono molto ansiosi di provarlo! Catturi questo comportamento in un metodo chiamato findGoodDeals()
, ma realizzi anche che ci sono molte cose disordinate coinvolte nella connessione ai mercati. Ad esempio, devi aprire un SocketChannel
,
public class StockTradeSystem implements ITradeSystem{
@Override
public void placeOrder(IOrder order);
getMarket().place(order);
@Override
public void ackOrder(IOrder order);
System.out.println("Order received" + order);
private void connectToMarket();
SocketChannel sock = Socket.open();
sock.bind(marketAddress);
<LOTS MORE MESSY CODE>
}
public void findGoodDeals();
deals = <apply magic wizardry>
System.out.println("The best stocks to buy are: " + deals);
}
Le implementazioni concrete avranno molti di questi metodi disordinati come connectToMarket()
, ma findGoodDeals()
è tutto ciò che interessa ai trader.
Ora è qui che entrano in gioco le classi astratte. Il tuo capo ti informa che anche i trader di valuta vogliono utilizzare il tuo sistema. E guardando i mercati valutari, vedi che l'impianto idraulico è quasi identico ai mercati azionari. In effetti, connectToMarket()
può essere riutilizzato alla lettera per connettersi ai mercati dei cambi. Tuttavia, findGoodDeals()
è un concetto molto diverso nell'arena valutaria. Quindi, prima di passare il codice base al mago del cambio dall'altra parte dell'oceano, esegui il refactoring in una abstract
classe, lasciandolo non findGoodDeals()
implementato
public abstract class ABCTradeSystem implements ITradeSystem{
public abstract void findGoodDeals();
@Override
public void placeOrder(IOrder order);
getMarket().place(order);
@Override
public void ackOrder(IOrder order);
System.out.println("Order received" + order);
private void connectToMarket();
SocketChannel sock = Socket.open();
sock.bind(marketAddress);
<LOTS MORE MESSY CODE>
}
Il tuo sistema di trading azionario implementa findGoodDeals()
come hai già definito,
public class StockTradeSystem extends ABCTradeSystem{
public void findGoodDeals();
deals = <apply magic wizardry>
System.out.println("The best stocks to buy are: " + deals);
}
ma ora il mago del FX può costruire il suo sistema semplicemente fornendo un'implementazione di findGoodDeals()
per le valute; non deve reimplementare le connessioni socket o anche i metodi di interfaccia!
public class CurrencyTradeSystem extends ABCTradeSystem{
public void findGoodDeals();
ccys = <Genius stuff to find undervalued currencies>
System.out.println("The best FX spot rates are: " + ccys);
}
La programmazione su un'interfaccia è potente, ma applicazioni simili spesso reimplementano metodi in modi quasi identici. L'uso di una classe astratta evita le reimplementazioni, pur preservando la potenza dell'interfaccia.
Nota: ci si potrebbe chiedere perché findGreatDeals()
non fa parte dell'interfaccia. Ricorda, l'interfaccia definisce i componenti più generali di un sistema di trading. Un altro ingegnere può sviluppare un sistema di trading COMPLETAMENTE DIVERSO, in cui non si preoccupano di trovare buoni affari. L'interfaccia garantisce che l'ufficio vendite possa interfacciarsi anche al proprio sistema, quindi è preferibile non intrappolare la tua interfaccia con concetti applicativi come "grandi affari".