- •Отношение вложенности
- •Расширение определения клиента класса
- •Отношения между клиентами и поставщиками
- •Сам себе клиент
- •Наследование
- •Построение родительского класса Found
- •Построение класса потомка Derived
- •Добавление и скрытие полей потомком
- •Конструкторы родителей и потомков
- •Добавление методов и изменение методов родителя
- •Статический контроль типов и динамическое связывание
- •Три механизма, обеспечивающие полиморфизм
- •Полиморфизм семейства классов Found и Derived
- •Пример работы с полиморфным семейством классов
- •Абстрактные классы
- •Класс ListStack - потомок абстрактного класса Stack
- •Класс ArrayList - потомок абстрактного класса Stack
- •Классы без потомков
Расширение определения клиента класса
До сих пор мы говорили, что клиент содержит поле, представляющее объект класса поставщика. Это частая, но не единственная ситуация, когда класс является клиентом другого класса. Рассмотрим еще три ситуации, когда один класс становится клиентом другого класса, хотя среди его полей и нет объектов, принадлежащих классу поставщика.
Первую возможную ситуацию демонстрирует процедура MainWindows-проекта. В ней "на лету" в момент вызова метода Run создается объект класса, наследуемого от класса Form. Создаваемый объект является результатом вычисления выражения, заданного операцией new. В этом случае у класса клиента нет ни поля, ни локальной переменной, связанной с объектом класса поставщика. Но и в этом случае клиент создает объект поставщика, передавая его затем в качестве аргумента методу Run класса Application.
Рассмотрим еще одну возможную ситуацию. В классе может быть метод, создающий локальный объект поставщика. Используя этот объект, в методе вызываются сервисы поставщика. Вся разница в том, что другим методам клиентского класса локальный объект недоступен и по завершении работы метода его жизнь заканчивается.
/// <summary>
/// Метод, использующий локальный объект класса provider
/// для работы с методами класса Provider
/// </summary>
/// <returns>композиция строк провайдера и клиента </returns>
public string MethodClient3()
{
Provider local_provider =
new Provider("Локальныйобъект Provider", 77);
string res = local_provider.MethodPD() + NEWLINE;
res += "Объекткласса Client" + NEWLINE;
res += string.Format("Моиполя: поле1 = {0}, поле2 = {1}",
fieldC1, fieldC2);
returnres;
}
Третья возможная ситуация - когда объекты поставщика не создаются ни конструктором, ни методами класса клиента, ни "на лету". Клиент использует готовый объект - модуль класса Provider, автоматически создаваемый для класса, у которого есть статические поля и статические методы. В этом случае класс поставщик сам создает свой статический объект, предоставляя возможность работы с ним всем своим клиентам. Через этот объект клиентам доступны только статические сервисы класса поставщика. Добавим в клиентский класс еще один метод:
/// <summary>
/// Метод, использующий модуль Provider
/// для работы со статическим методом класса Provider
/// </summary>
/// <returns>композиция строк провайдера и клиента </returns>
public string MethodClient2()
{
string res = Provider.MethodPS() + NEWLINE;
res += "Объекткласса Client" + NEWLINE;
res += string.Format("Моиполя: поле1 = {0}, поле2 = {1}",
fieldC1, fieldC2);
returnres;
}
Дадим теперь расширенное определение клиента.
Класс B называется клиентом класса A, если в классе B создаются объекты класса A или вызываются статические сервисы класса A.
Под сервисом класса понимается метод или поле класса, доступное клиентам, то есть объявленное с модификатором public или internal. Статический сервис - это сервис, объявленный с модификатором static.