Главная » C# » Представление идей с помощью интерфейсов С# – приложение для вычисления налогов Visual C# (Sharp)

0

Интерфейсы  С#  можно  рассматривать  как  программные  конструктивные  блоки, с помощью которых можно по-быстрому записать свои идеи.  В процессе нахоения  решения  проблемы  мы обычно записываем одну идею,  на основе  которой у нас рождается другая, из которой следует третья и т. д., пока мы не набросаем все идеи.

Первая идея обычно является центральной. В нашем  приложении для  вычисления налогов центральной идеей является сам движок для вычисления налогов. Движок для вычисления налогов применяется для операции, отображенной в его названии, т. е. для вычисления налогов,  и  как связывающий компонент для  всех других элентов программы. Эти другие элементы представляют собой некие неопределеые понятия, необходимые для завершения приложения вычисления налогов. Лио я предпочитаю называть эти прочие компоненты зависимостями (dependencies). Зависимость — это идея, требуемая для завершения предыдущей идеи.

Сами идеи представляют собой план решения определенной проблемы или дают представление, каким это решение должно быть. Идея, воплощенная в исходный код, становится чертежом, который принуждает определенную форму реализации. Идеи, изложенные в исходном коде С#, называются интерфейсами; самостоятельно исполняться интерфейсы не могут. С  точки  зрения  программирования,  интеейс сродни абстрактному базовому классу, в том, что к нему можно обращаться, но с него нельзя создать экземпляр. Чтобы идея заработала, создается ее реализия, или реализация интерфейса.

Вот пример объявления интерфейса:

interface IExample { }

В объявлении интерфейса ключевое слово interface ассоциируется с идентификором IExample; с точки зрения синтаксиса, оно используется подобно ключевому слову class. Интерфейсу можно присвоить общую (public) область видимости. Интерфейс содержит методы  и свойства,  которые определяют поведение классов, реализующих интерфейс. Рассмотрим пример интерфейса, содержащего один мод и одно свойство:

interface IExample { void Method();

int Property { get; set;  }

}

Свойства и методы интерфейса определяются в фигурных скобках после идентикатора интерфейса. После самих методов и свойств фигурные скобки не примяются, т. к. мы  создаем только  сигнатуру метода или свойства, а их реализация будет выполнена классом. Опять же, данный процесс похож на определение абсактного метода абстрактного базового класса.

Вот простой пример реализации определенного интерфейса:

class Examplelmplementation : IExample { public void Method() { }

public int Property { get { }

set { }

}

}

Здесь интерфейс IExample реализуется с помощью механизма наследования, побно реализации абстрактного базового класса, рассмотренного в предыдущей главе.

ПРИМЕЧАНИЕ

Язык С# и среда CLR являются моделями единичного наследования, в том, что прзводный класс может иметь только один базовый класс. Но в С# класс может реали-

зовать столько интерфейсов, сколько необходимо. Если класс  наследует  от  другог о класса или интерфейса, то первы м идентификаторо м после двоеточи я являетс я им я наследуемог о  класса.  Применени е  другого  формат а  вызовет  ошибку  компилятора .

При  реализации  интерфейса  в  классе  должны  быть  реализованы  все  его  методы и свойства. В противном случае при компиляции исходного кода компилятор васт сообщения об отсутствующих методах или свойствах и будет считать реалацию незавершенной.

Так как для реализации интерфейса применяется механизм наследования, то иерфейс можно рассматривать как базовый класс, не имеющий реализации. В слующем фрагменте кода иллюстрируется создание экземпляра реализации интеейса и присвоение этого экземпляра переменной интерфейса:

IExample els = new Examplelmplementation(); els.Method();

В  данном  примере  создается  экземпляр  класса  Examplelmplementation, который присваивается переменной  els типа  IExample. Данное создание экземпляра и его присвоение  является  понижающим  приведением  производного  класса  к базовому классу,  или,  более  верно,  к базовому типу.  Понижающее  приведение  происходит, когда производный тип в цепочке наследования (например, Examplelmplementation) приводится  к  базовому  классу  в  цепочке  наследования  (например,  к  IExample). Автоматическое   понижающее   приведение   является   возможным,    потому    что Examplelmplementation можно выразить, как тип IExample. Это как будто бы вы говорите:   "Я  создаю  экземпляр  класса  Examplelmplementation и  присваиваю ему   тип     IExample, находящийся    в   иерархии    наследования".    При   вызове метода  cls.Methodo, вызывающий   код  в  действительности   вызывает   метод Examplelmplementation.Method(), ХОТЯ  ОН  И не знает об ЭТОМ,  Т.  К. ОН  ИСПОЛЬЗует базовый ТИП IExample.

В то время как механика определения интерфейса и его соответствующей реализии является довольно простой, вопрос заключается в том, зачем заниматься всем этим? Попробуем найти ответ на этот вопрос с помощью еще одной аналогии.

Допустим, вы пришли в ресторан поужинать. Сидя за столом, вы ожидаете, что официант  возьмет  ваш  заказ,  принесет заказанные  блюда,  уберет  пустую  посуду, а в конце ужина принесет вам счет. Все эти действия являются идеями, применяимися для управления рестораном. Вы пользуетесь этой идеей, как и миллионы других клиентов, т. к. эта идея применяется во всех ресторанах.

Подумайте  над сказанным  немного.  Идеей является официант, но ее реализацией являет человек.  Усаживая  вас за стол,  ваш официант может представиться, но вы когда-либо обращались к официанту по имени? Большинство людей обычно так и обращается  к нему — официант, т. к. они видят в нем  не человека, а кого-то, кто обслуживает их. Суть заключается в том, человек — это всего лишь реализация, но нас он  действительно  не  интересует  как  человек,  а только  как официант,  выпояющий свои функции. Например, хотя вы можете посочувствовать, если у вашего официанта выдался плохой день, тем не менее, вы не хотите, чтобы это отразилось

на вашем ужине. А еще более прямолинейно, то нам, скорее всего, было бы совсем безразлично, если бы любимую кошку официанта забрали шкуродеры.

Вот это и есть суть интерфейсов и реализаций. Интерфейс определяет роль с задами, которые реализации должна выполнять. Вас не интересует, может ли реалация делать что-либо другое, или если у нее "плохой день". Все, что вас интерест, — это только то, чтобы реализация делала то, что интерфейс ее обязывает делать.

Что  мы  здесь  имеем, так это развязывание идеи от интерфейса, точно так же,  как и в ресторане, где нам безразлично, зовут ли нашего официанта Петей, Васей, Сей или Галей в случае официантки. Более того, слишком ли вас волновало, если бы вместо человека вас обслуживал робот? Скорее всего, что нет, т. к. единствеое, что вас заботит, — это хорошо поужинать. Это является важным аспектом иерфейсов и реализаций: реализации заменяемы, и мы можем заменить одну реалацию другой.

При использовании интерфейсов и типов, реализующих их, мы пишем компонено-ориентированное программное обеспечение. Компоненты и наследование явлтся двумя разными объектно-ориентированными технологиями. Наследование применяется для реализации интерфейсов, а компоненты — для воплощения идей.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии