Здесь есть много отличных ответов, но я часто нахожу использование ОБЕИ интерфейсов и абстрактных классов лучшим путем. Рассмотрим этот надуманный пример:
Вы разработчик программного обеспечения в инвестиционном банке и вам необходимо создать систему, которая размещает заказы на рынке. Ваш интерфейс отражает самое общее представление о том, что делает торговая система ,
1) Trading system places orders
2) Trading system receives acknowledgements
и может быть захвачен в интерфейсе, ITradeSystem
public interface ITradeSystem{
public void placeOrder(IOrder order);
public void ackOrder(IOrder order);
}
Теперь инженеры, работающие в отделе продаж и других направлениях бизнеса, могут начать взаимодействовать с вашей системой, чтобы добавить функциональность размещения заказов в свои существующие приложения. И вы еще даже не начали строить! В этом сила интерфейсов.
Итак, вы продолжаете создавать систему для биржевых трейдеров; они слышали, что в вашей системе есть функция поиска дешевых товаров, и очень хотят попробовать ее! Вы фиксируете это поведение с помощью вызываемого метода findGoodDeals()
, но при этом понимаете, что при подключении к рынкам задействовано много беспорядка. Например, вам нужно открыть 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);
}
В конкретных реализациях будет много таких грязных методов connectToMarket()
, но findGoodDeals()
это все, что действительно волнует трейдеров.
А теперь в игру вступают абстрактные классы. Ваш босс сообщает вам, что валютные трейдеры также хотят использовать вашу систему. И глядя на валютные рынки, вы видите, что водопровод почти идентичен фондовым рынкам. Фактически, connectToMarket()
можно дословно повторно использовать для подключения к валютным рынкам. Однако findGoodDeals()
на валютной арене это совсем другая концепция. Поэтому, прежде чем передать кодовую базу парню-валютному магу через океан, вы сначала реорганизуете abstract
класс, оставляя findGoodDeals()
нереализованные
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>
}
Ваша система торговли акциями реализует, findGoodDeals()
как вы уже определили,
public class StockTradeSystem extends ABCTradeSystem{
public void findGoodDeals();
deals = <apply magic wizardry>
System.out.println("The best stocks to buy are: " + deals);
}
но теперь вундеркинд FX может построить свою систему, просто предоставив реализацию findGoodDeals()
для валют; ей не нужно заново реализовывать соединения сокетов или даже методы интерфейса!
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);
}
Программирование для интерфейса - это мощное средство, но похожие приложения часто повторно реализуют методы почти одинаковыми способами. Использование абстрактного класса позволяет избежать повторных реализаций, сохраняя при этом мощь интерфейса.
Примечание: можно задаться вопросом, почему findGreatDeals()
не является частью интерфейса. Помните, что интерфейс определяет самые общие компоненты торговой системы. Другой инженер может разработать СОВЕРШЕННО ДРУГУЮ торговую систему, в которой он не заботится о поиске хороших сделок. Интерфейс гарантирует, что отдел продаж также может взаимодействовать со своей системой, поэтому желательно не связывать ваш интерфейс с концепциями приложения, такими как «выгодные предложения».