Поиск

Сокрытие имени с помощью интерфейсов

'Чтобы вызвать метод, реализованный в интерфейсе, необходимо привести экземпляр этого класса к типу интерфейса и вызвать нужный ме-цод — это самый распространенный подход. Хотя это работает и многие (включая и меня) используют эту методику, формально вы вовсе не обязаны приводить объект к реализованному им интерфейсу, чтобы вы-зывать методы этого интерфейса. Этот так, потому что методы интерфейса, реализованные классом, также являются открытыми методами Цасса. Взгляните на код на С#, особенно на метод Main, чтобы понять, что я имею в виду:

using System;
public interface IDataBound {
void BindQ; }
public class EditBox : IDataBound
{
// Реализация IDataBound. public void BindQ
{
Console.WriteLineC'Binding to data store...");
} }
class NameHidingUpp
{
II Точка входа Main, public static
void MainQ {
Console.WriteLine();
EditBox edit = new EditBox();
Console.WriteLine("Calling EditBox.Bind()...");
edit.BindO;
Console.WriteLine();
IDataBound bound = (IDataBound)edlt;
Console.WriteLine("Calling

(IDataBound)EditBox.Bind()...");

bound.Bind();
> } I Теперь этот пример выдаст следующее: /
Calling EditBox.Bind()... J Binding to data store... •
/'
Calling (IDataBound))EditBox.Bind()... ;
Binding to data store... '

Заметьте: хотя это приложение вызывает реализованный метод Btyid двумя способами — с помощью приведения и без него, оба вызова кс|р-ректно функционируют, в том смысле, что Bind выполняется. Хотя цо- началу возможность прямого вызова реализованного метода без приведения объекта к интерфейсу может показаться неплохой, порой это более чем нежелательно. Самая очевидная причина этого то, что реализация нескольких интерфейсов, каждый из которых может содержать массу членов, может привести к быстрому засорению отрытого пространства имен вашего класса членами, не имеющими значения за пределами видимости реализующего эти интерфейсы класса. Вы можете не позволять реализованным членам интерфейсов становиться открытыми членами класса, применяя методику сокрытия имен (name hiding).

В простейшем случае сокрытие имен представляет собой возможность скрывать имя унаследованного члена от любого кода за пределами производного или реализующего его класса [его часто называют внешним миром (outside world)]. Возьмем тот пример, где класс EditBox должен был реализовывать интерфейс IDataBound, но на этот раз EditBox не должен предоставлять методы IDataBound внешнему миру. Этот интерфейс нужен ему скорее для собственных нужд, или, возможно, программист просто не хочет засорять пространство имен класса многочисленными методами, которые обычно не используются клиентом. Чтобы скрыть член реализованного интерфейса, нужно лишь удалить модификатор доступа члена public и квалифицировать имя члена именем интерфейса:

using System;
public interface IDataBound {
void Bind();
}
public class EditBox : IDataBound
1 // реализация IDataBound. I void IDataBound.Bind()
| <
| Console.WriteLine("Binding to data store...");
\ }
}\
cl ss NameHiding2App {
public static void MainQ
{
Console.WriteLine();
EditBox edit = new EditBoxO;
Console.WriteLine("Calling EditBox. BindQ...");
// ОШИБКА: эта строка не будет компилироваться, так как
// метод Bind более не существует в пространстве имен // класса EditBox. edit.BindQ;
Console. WriteLineO;
IDataBound bound = (IDataBound)edit;
Console.WriteLine("Calling (IDataBound)EditBox.BindQ...");
// Это правильно, так как объект был сначала приведен
// к IDataBound.
bound.Bind(); } >

Этот код не будет компилироваться, так как имя члена Bind более не является частью класса EditBox. Поэтому данная методика позволяет вам удалять член из пространства имен класса, в то же время разрешая явный доступ к нему с помощью операции приведения.
Повторю: при сокрытии члена вы не можете применять модификатор доступа. При попытке использования модификатора доступа с членом реализованного интерфейса вы получите ошибку периода компиляции. Может, это покажется странным, но поймите, что общая причина, заставляющая скрыть что-то, — желание сделать эту сущность невидимой за пределами текущего класса. Так как модификаторы доступа существуют лишь для определения уровня видимости за пределами базо- , вого класса, при сокрытии имен они не имеют смысла.