Явная реализация интерфейса

Явная реализация интерфейса

В определении IDraw3D мы были вынуждены назвать наш единственный метод Draw3D(), чтобы избежать конфликта с абстрактным методом Draw(), определенным в базовом классе Shape. Такое определение интерфейса вполне допустимо, но более естественным именем для метода было бы Draw().

// Изменение имени с "Draw3D" на "Draw".

public interface IDraw3D {

 void Draw();

}

Если вносить такое изменение, то потребуется также обновить нашу реализацию DrawIn3D().

public static void DrawIn3D(IDraw3D itf3d) {

 Console.WriteLine("-› Отображение IDraw3D-совместимоuо типа");

 itf3d.Draw();

}

Теперь предположим, что мы определили новый класс Line (линия), который получается из абстрактного класса Shape и реализует iDraw3D (оба из них теперь определяют одинаково названные абстрактные методы Draw()).

// Проблемы? Это зависит.

public class Line: Shape, IDraw3D {

 public override void Draw() {

  Console.WriteLine("Отображение линии…");

 }

}

Класс Line компилируется беспрепятственно. Рассмотрим следующую логику Main().

static void Main(string[] args) {

 …

 // Вызов Draw().

 Line myLine = new Line();

 myLine.Draw();

 // Вызов той же реализации Draw()!

 IDraw3D itfDraw3d = (IDraw3D)myLine;

 itfDraw3d.Draw();

}

С учетом того, что вы уже знаете о базовом классе Shape и интерфейсе IDraw3D, это выглядит так как будто вы вызываете два варианта метода Draw() (один с объектного уровня, а другой – с помощью интерфейсной ссылки). Однако компилятор способен вызывать одну и ту же реализацию и с помощью интерфейса, и с помощью объектной ссылки, поскольку абстрактный базовый класс Shape и интерфейс IDraw3D имеют одинаково названные члены. Это может оказаться проблемой, когда вы хотите, чтобы метод IDraw3D.Draw() представлял тип во всей трехмерной (3D) "красе", а не в неказистом двухмерном представлении переопределённого метода Shape.Draw().

Теперь рассмотрим родственную проблему. Что делать, если вам нужно гарантировать, что методы, определенные данным интерфейсом, будут доступны только с помощью интерфейсных ссылок, а не объектных? В настоящий момент члены, определенные интерфейсом IPointy, доступны как с помощью объектных ссылок, так и по ссылке на IPointy.

Ответ на оба вопроса дает явная реализация интерфейса. Используя этот подход, вы можете гарантировать, что пользователь объекта сможет получить доступ К методам, определенным данным интерфейсом, только с помощью правильной интерфейсной ссылки, не допуская при этом конфликта имен. Для примера рассмотрите следующий обновленный класс Line (предполагая, что вы соответствующим образом обновили Hexagon и Circle).

// Используя явную реализацию метода, можно указать

// другие реализации Draw() .

public class Line: Shape, IDraw3D {

 // Этот метод можно вызвать только ссылкой на интерфейс IDraw3D.

 void IDraw3D.Draw() { Console.WriteLine("Отображение ЗD-линии…"); }

 // Это можно вызвать только на уровне объекта.

 public override void Draw() { Console.WriteLine("Отображение линии…"); }

 …

}

Как видите, при явной реализации члена интерфейса общий шаблон выглядит так: возвращаемоеЗначение ИмяИнтерфейса.ИмяМетода(аргументы). Здесь есть несколько "подводных камней", о которых следует знать. Прежде всего, не допускается определять явно реализуемые члены с модификаторами доступа. Например, следующий синтаксис недопустим.

// Нет! Это недопустимо.

public class Line: Shape, IDraw3D {

 public void IDraw3D.Draw() { // ‹= Ошибка!

  Console.WriteLine("Отображение 3D-линии…");

 }

 …

}

Главной причиной использования явной реализации метода интерфейса является необходимость "привязки" соответствующего метода интерфейса к уровню интерфейса. Если добавить ключевое слово public, то это будет означать, что данный метод является членом открытого сектора класса, и "привязка" будет отменена. Тогда вызывающая сторона сможет вызывать только метод Draw(), определенный базовым классом Shape на объектном уровне.

// Здесь вызывается переопределенный метод Shape.Draw().

Line myLine = new Line();

myLine.Draw();

Чтобы вызвать метод Draw(), определенный с помощью IDraw3D, мы должны явно получить интерфейсную ссылку, используя любой из ранее указанных подходов. Например:

// Это обеспечит вызов метода IDraw3D.Draw().

Line myLine = new Line();

IDraw3D i3d = (IDraw3D) myLine;

i3d.Draw();

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

7.3.2 Реализация

Из книги C++ автора Хилл Мюррей

7.3.2 Реализация Реализующие slist функции в основном просты. Единственая настоящая сложность – что делать в случае ошибки, если, например, пользователь попытается get() что-нибудь из пустого списка. Мы обсудим это в #7.3.4. Здесь приводятся определения членов slist. Обратите


Реализация

Из книги Тонкости реестра Windows Vista. Трюки и эффекты автора Клименко Роман Александрович


Элементы интерфейса

Из книги Справочное руководство по C++ автора Страустрап Бьярн

Элементы интерфейса Теперь поговорим об отключении или включении отдельных элементов интерфейса.Отключение анимацииОтключить все эффекты анимации можно с помощью параметра REG_DWORD-типа TurnOffSPIAnimations, расположенного в ветви реестра HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer.


Тип интерфейса

Из книги Adobe Photoshop CS3 автора Завгородний Владимир

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


Общий вид интерфейса

Из книги Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ автора Мейерс Скотт

Общий вид интерфейса Первого же взгляда на программу Adobe Photoshop (рис. 6.1) достаточно, чтобы увидеть знакомые элементы управления: кнопки управления окном, строку меню, полосы прокрутки у отдельных окон. В то же время есть и полностью незнакомые элементы. Мы рассмотрим их


Реализация паттерна««Шаблонный метод» с помощью идиомы невиртуального интерфейса

Из книги Технологии программирования автора Камаев В А

Реализация паттерна««Шаблонный метод» с помощью идиомы невиртуального интерфейса Начнем с интересной концепции, которая утверждает, что виртуальные функции почти всегда должны быть закрытыми. Сторонники этой школы предполагают, что правильно было бы оставить


12.10. РЕАЛИЗАЦИЯ

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

12.10. РЕАЛИЗАЦИЯ Обычно на этапе кодирования всплывают все неприятные проблемы, которые только можно себе представить. Чем больше проект, тем больше проблем. Вот почему первые три шага так важны.Если все из вышеописанных шагов полностью пройдены, то реализация программы


14.5. Реализация

Из книги 3ds Max 2008 на 100 % автора Верстак Владимир Антонович

14.5. Реализация Теперь мы приступим к реализации нашей оболочки, следуя тем идеям, которые обсуждались в предыдущем разделе. На рис. 14.9 показаны основные объекты, которыми манипулирует оболочка. Цель — это вопрос, подлежащий рассмотрению; Трасса — это цепочка,


1.1. Элементы интерфейса

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

1.1. Элементы интерфейса Первое, что вы увидите после запуска программы 3ds Max 2008, – ее основное окно (рис. 1.1).Если вы начинающий пользователь и не встечались с интерфейсом программы, сначала осмотрите элементы и ознакомьтесь с окружением. Вы увидите, что интерфейс


11.2. Реализация

Из книги Операционная система UNIX автора Робачевский Андрей М.

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


Реализация TCP/IP

Из книги C++ для начинающих автора Липпман Стенли

Реализация TCP/IP Прежде чем перейти к описанию функционирования модулей протоколов TCP/IP, рассмотрим еще одну структуру данных, называемую управляющим блоком протокола (Protocol Control Block, PCB), который в случае TCP/IP называется Internet PCB, и представлен структурой inpcb, определенной в


10.6. Явная специализация шаблона А

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

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


17.5. Конфигурация интерфейса

Из книги автора

17.5. Конфигурация интерфейса Один из шагов, выполняемых многими программами, работающими с сетевыми интерфейсами системы, — это получение от ядра списка всех интерфейсов, сконфигурированных в системе. Это делается с помощью вызова SIOCGIFCONF, использующего структуру ifconf,