В нашем примере статический конструктор был реализован с жестко закодированным названием компании. Еще реальнее было бы прочитать запись в реестре или файл или соединиться с базой данных, чтобы найти название компании. Между прочим, поскольку поле companyName объявлено как статическое и только для чтения, то статический конструктор является единственным местом, где полю можно законно присвоить значение. Осталось сделать одну последнюю вещь — определить открытое свойство, которое позволяет получить доступ к названию компании.

public static string сompanyName {

 get {

  return companyName;

 }

}

Свойство companyName также было объявлено как статическое, и теперь можно видеть реальное значение статическою метода или свойства метод или свойство может быть объявлен как статический, если он обращается только к статическим полям, и не обращается ни к каким данным, которые ассоциируются с определенным объектом.

Как мы уже видели, синтаксис вызова статических членов класса извне класса слегка отличается от используемого для других членов, так как статический член ассоциирован с классом, а не с каким-то объектом, то для его вызова используется имя класса, а не имя переменной:

string Company = Employee.CompanyName;

Концепция статических членов является очень мощной и предоставляет полезные средства классу для реализации любой функциональности, которая является одинаковой для каждого объекта этого класса. Единственным способом, которым можно добиться чего-то подобного в VB, является определение глобальных переменных. Однако, если сделать это, то глобальные переменные имеют недостаток, заключающийся в том, что они не связаны с каким-то классом, что ведет также к вопросам конфликта имен.

Другими ситуациями, где используются статические члены класса, являются:

□ Возможная реализация свойства MaximumLength для нашего класса Employee или любого другого класса, содержащего имя, если необходимо определить максимальную длину имени.

□ В C# большинство цифровых типов данных имеют статические свойства, которые указывают их максимальные значения. Можно, например, определить наибольшие значения, которые хранятся в int и float:

int MaxIntValue = int.MaxValue;

float MaxFloatValue = float.MaxValue;

Наследование

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

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

Как можно при создании кода в VB обновить наше приложение? Существуют два возможных подхода, но оба они имеют серьезные недостатки. Можно:

□ Написать новый класс Manager

□ Изменить класс Employee

Создание нового класса является, вероятно, тем подходом, который потребует меньше всего работы так как можно начать с простого копирования кода модуля класса Employee и затем изменить эту копию кода. Проблема состоит в том, что Employee и Manager имеют такой большой объем общего кода, как весь код, связанный со свойствами Name, CompanyName и Salary. Дублирование одного и того же кода является опасным. Что произойдет, если в некоторый момент какая-то причина заставит изменить код? Плохой разработчик надеется не забыть внести одинаковые изменения в оба класса. Это самый простой способ создания ошибок. Другая проблема состоит в том, что теперь существуют два несвязанных класса Employee и Manager, с которыми должен иметь дело код клиента, что скорее всего сделает его написание затруднительным. (Хотя можно обойти эту проблему, помещая общие свойства в интерфейс и реализуя этот интерфейс в обоих классах Employee и Manager.)

Альтернативным способом является написание класса Manager и размещение объекта Employee внутри него как переменной с областью действия класса. Это решает проблему дублирования кода, но по-прежнему оставляет нас с двумя различными объектами, а также с неудобным, непрямым синтаксисом для вызова методов и свойств сотрудника (objManager.objEmployее.Name и т.д.).

Если выбрать модификацию модуля класса сотрудника, то по-видимому надо добавить дополнительное поле типа Boolean, которое указывает, является ли Employee менеджером или нет. Затем в соответствующих частях кода это Boolean будет проверяться в инструкции if, чтобы знать, что делать. Это решает проблему двух несвязанных классов — снова имеется только один класс. Однако это вносит новую трудность: как было специально сказано ранее, поддержку для менеджеров решено было добавить примерно год спустя. Это означает, что модуль класса Employee был по-видимому поставлен, протестирован, полностью отлажен и известно, что он работал правильно. В этой ситуации вряд ли возникнет желание обращаться к работающему коду, чтобы изменить его, учитывая связанный с этим риск внесения новых ошибок.

Другими словами, мы достигли точки, где VB не может предложить никакого удовлетворительного решения. Из заголовка этого раздела нетрудно сделать заключение, что C# предлагает способ решения этой проблемы с помощью использования наследования.

Мы уже видели, что наследование включает добавление или замену свойств классов. В предыдущем примере класс SquareRootForm добавил код к классу .NET System.Windows.Forms.Form. Он определил элементы управления для размещения в SquareRootForm как поля-члены, а также добавил обработчик событий. В примере Employee будут продемонстрированы как добавление, так и замена свойств базового класса, а также определен класс Manager, который является производным из класса Employee. Мы добавим поле и свойство, представляющие бонус, и заменен метод GetMonthlyPayment() (для полноты также будет заменен метод ToString(), чтобы он выводил бонус вместе с именем и зарплатой). Все это означает, что будет получен отдельный класс. Но при этом не потребуется дублировать никакой код и вносить большие изменения в класс Employee. Может показаться, что по-прежнему существует проблема двух различных классов, что делает более трудным написание клиентского кода, но, как будет продемонстрировано позже, C# имеет ответ и на это.

Наследование от класса Employee

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату