Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 8
На сайте нет зарегистрированных пользователей

Пользователей: 13,368
новичок: Goosprin
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Метод конечных разностей для интерполяции/экстраполяции на Delphi
Расчет мер близости на отношениях на Delphi + Пояснительная записка
Поиск пути в графе заданном списками инцедентности на Turbo Pascal

Отделение интерфейса от реализации
Решение, представленное в предыдущем разделе, хоть и правильное, но имеет уже упомянутый недостаток: необходимо транслировать программу целиком. Между тем не хотелось бы компилировать каждый раз заново уже проверенные и отлаженные модули. Если модуль не изменяется, то можно оттранслировать его один раз, а потом просто компоновать с остальными — именно так поступают с библиотечными функциями.
Для этого разделим наш модуль с классом TStack на две части: интерфейс и реализацию. Интерфейс класса является его определением, хотя для методов указаны только прототипы. Но по интерфейсу компилятор может вычислить размер класса, поэтому интерфейса достаточно, чтобы объявлять объекты этого класса.
Файл с интерфейсом назовем TStack.h, а файл с реализацией пусть, как и прежде, имеет имя TStack.cpp. Файл TStack.h называется заголовком (header), и именно он подключается к другим модулям с помощью препроцессора. Стража нужно прописать в нем (листинг 13.5).

Листинг 13.5. Файл TStack.h — интерфейс класса TStack
#ifndef _STACK #define _STACK class TStack { public: TStackO:
void push(void *d); void *top()const: void *pop(): bool emptyO const: private:
struct Elem:
Elem * Head:
TStack(const TStack &); // закрыли копирование
TStack& operator=(const TStack &); // закрыли присваивание
};
#endif /* _STACK */
В проекте два файла: файл реализации TStack.cpp и файл main.cpp с программой-клиентом.
Файл реализации просто включается в проект интегрированной среды1. Естественно, интерфейс класса обязан присутствовать и в этом файле (листинг 13.6).
Листинг 13.6. Файл TStack.cpp — реализация класса TStack
#include "TStack.h" // подключение интерфейса
struct TStack::Elem { void *data; Elem *next;
Elem (void *d, Elem *p): data(d). next(p) { }
};
TStack::TStack(): Head(0), count(0) {} void TStack::push(void *d) { Head = new Elem(d, Head); } void * TStack::top() const { return Head? Head->data:0; } void * TStack::pop() { if (Head == 0) return 0; void *top = Head->data;
Elem *oldHead = Head; Head = Head->next; delete oldHead; return top;
}
bool TStack::empty() const { return Head==0; }



В программе-клиенте тоже подключается только интерфейс (листинг 13.7).
Опубликовал Kest January 16 2014 12:56:42 · 13 Комментариев · 3911 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Павел January 17 2014 17:13:18
Интерфейс и реализация, это то на чем держатся многие современные объектно-ориентированные языки программирования.

Благодаря такой реализации можно достичь высокую прозрачность кода в плане его читабельности, а также создать предпосылки для его масштабируемость в будущем. Кроме того этот подход даст вам возможность создавать серьезные проекты с хорошо читаемой структурой и иерархией.
Вадим January 18 2014 08:44:35
Сейчас на данной парадигме строятся все языки высокого уровня (ООП). Это и понятно, ведь проекты становятся все сложнее и сложнее, а код при этом не упрощается.

По сути это этап эволюции самих языков программирования, где данная парадигма является его следующей ступенью в развитии. Интересно, что будет дальше?
Александр January 18 2014 22:41:30
Необходимо транслировать программу целиком точно подмечено. Важна проработка и целевой анализ кода не только на "интерфейс-этапе" , но и про реализацию не стоит забывать. Время не стоит на месте, написание начинает носить иной характер, совсем не тот, что пару лет назад был доступен почти каждому начинающему программисту. Очень важно понимать и разделять 2 тесно связанных понятия : иерархия и структура.
Михаил January 19 2014 14:39:55
smiley Хотя методика использования классов-дескрипторов имеет свои преимущества и безусловно приближает нас к возможности безопасного извлечения классов из DLL, она также имеет свои недостатки. Хочу заметити, что класс интерфейса вынужден явно передавать каждый вызов метода классу реализации. Для простого класса вроде FastString только с двумя открытыми операторами, конструктором и деструктором, это не проблема. Для большой библиотеки классов с сотнями или тысячами методов написание этих передающих процедур было бы весьма утомительным и явилось бы потенциальным источником ошибок. Наконец, методика классов-дескрипторов не полностью решает проблемы совместимости транслятора/компоновщика, а они все же должны быть решены, если мы хотим иметь основу, действительно пригодную для создания компонентов повторного использования. Если я не прав прошу уточнить в чем или поправить меня smiley
Борис January 19 2014 19:42:29
Главное отличие класса от интерфейса — в том, что класс состоит из интерфейса и реализации.

Любой класс всегда неявно объявляет свой интерфейс — то, что доступно при использовании класса извне. Если у нас есть класс Ключ и у него публичный метод Открыть, который вызывает приватные методы Вставить, Повернуть и Вынуть, то интерфейс класса Ключ состоит из метода Открыть. Когда мы унаследуем какой-то класс от класса Ключ, он унаследует этот интерфейс. Может немного не по теме, но как то так товарищиsmiley
Вениамин January 19 2014 19:48:46
Борис, послушай, кроме этого интерфейса, у класса есть также реализация — методы Вставить, Повернуть, Вынуть и их вызов в методе Открыть. Между прочим наследники Ключа, наследуют вместе с интерфейсом также реализацию.

Вот здесь я вам скажу ребят... именно здесь таятся проблемы. итак, предположим, у нас есть некоторая модель, которая предполагает использование ключа для открытия двери. Также Она знает интерфейс Ключа и поэтому вызывает метод Открыть. \кто не согласен , пишите.
Генадий January 19 2014 19:56:31
когдато совсем давно был замечательный клас-интерфейс, такой который имел и protected (конструктор) между прочим по-умолчанию... так же деструктор только уже виртуальный. он имел запрещенные в свою очередь констуктор копирования иприсваивания\\ . И было так у него всего две реализации: назовем их мы AlphaGraphics и 2я BetaGraphics.
Деонис January 19 2014 20:01:16
Восходящее преобразование имеет место даже в такой простой команде: Shape s = new CircleO;

Здесь создается объект Circle, и полученная ссылка немедленно присваивает­ся типу Shape. На первый взгляд это может показаться ошибкой (присвоение одного типа другому), но в действительности все правильно, потому что тип Circle (окружность) является типом Shape (фигура) посредством наследования. Компилятор принимает команду и не выдает сообщения об ошибке.
Яков January 19 2014 20:05:01
Базовый класс Shape устанавливает общий интерфейс для всех классов, про­изводных от Shape — то есть любую фигуру можно нарисовать (draw()) и сте­реть (erase()). Производные классы переопределяют этот интерфейс, чтобы реа­лизовать уникальное поведение для каждой конкретной фигуры. Это я еще на 1 курсе Рыбтеха знал.
Юлий January 19 2014 20:06:52
Яков, добавлю вот еще чего: Класс RandomShapeGenerator — своего рода «фабрика», при каждом вызове метода next() производящая ссылку на случайно выбираемый объект Shape. За­метьте, что восходящее преобразование выполняется в командах return, каждая из которых получает ссылку на объект Circle, Square или Triangle, а выдает ее за пределы next() в виде возвращаемого типа Shape. Таким образом, при вызове этого метода вы не сможете определить конкретный тип объекта, поскольку всегда получаете просто Shape.
Цикорий January 19 2014 20:08:31
Метод main() содержит массив ссылок на Shape, который заполняется после­довательными вызовами RandomShapeGenerator.next(). К этому моменту вам из­вестно, что имеются объекты Shape, но вы не знаете об этих объектах ничего конкретного (так же, как и компилятор). Но если перебрать содержимое масси­ва и вызвать draw() для каждого его элемента, то, как по волшебству, произой­дет верное, свойственное для определенного типа действие — в этом нетрудно убедиться, взглянув на результат работы программы.
Щебра January 19 2014 20:14:03
Итак, Случайный выбор фигур в нашем примере всего лишь помогает понять, что компилятор во время компиляции кода не располагает информацией о том, ка­кую реализацию следует вызывать. Все вызовы метода draw() проводятся с при­менением позднего связывания. Согласитесь все логично и без данного метода впринципе не обойтись..
Изольда January 19 2014 20:36:30
Теперь вернемся к программе Music.java. Благодаря полиморфизму вы можете добавить в нее сколько угодно новых типов, не изменяя метод tune(). В хорошо спланированной ООП-программе большая часть ваших методов (или даже все методы) следуют модели метода tune(), оперируя только с интерфейсом базового класса.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Рисование PopupMenu
С/C++ Программиро...
SMLPack v1.0
Delphi 6. Учебный...
Midi
ЯЗЫК ПРОГРАММИРОВ...
Трассировка прово...
DirHTMLReportBuil...
PHP 5
Философия C++. Пр...
Таймер и секундомер
Delphi7 Для профе...
Х. М. Дейтел, П. ...
De Knop
Мониторинг сервер...
Error mod
MPTools
AJAX и PHP. разра...
Progressbar
Delphi 2005 для W...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97833
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14191
Borland Delphi ... 10291
Turbo Pascal fo... 7373
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Решение задачи ман...
Триггеры проверки
В текстовом файле ...
Другие вариации фи...
Драйвер ip
Демонстрация работ...
21 Д Безопасность ...
• устранение непол...
Подсчет количества...
Копирование и удал...
Введение
Рис. 10.2. Разреже...
MissingMappingAction
Безызбыточное коди...
Интерпретация симв...
Лечение зубов
Змейка на Visual P...
7.10. Просеивай ...
Потребность в глоб...
Information Center...
Стяжка пола
компьютеров
Онлайн казино Slot...
Отправка по факсу ...
Фотоаппарат и всп...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?