17. Наследование и подтипизация классов
17. Наследование и подтипизация классов
В главе 6 для иллюстрации обсуждения абстрактных контейнерных типов мы частично реализовали систему текстового поиска и инкапсулировали ее в класс TextQuery. Однако мы не написали к ней никакой вызывающей программы, отложив реализацию поддержки формулирования запросов со стороны пользователя до рассмотрения объектно-ориентированного программирования. В этой главе язык запросов будет реализован в виде иерархии классов Query с одиночным наследованием. Кроме того, мы модифицируем и расширим класс TextQuery из главы 6 для получения полностью интегрированной системы текстового поиска.
Программа для запуска нашей системы текстового поиска будет выглядеть следующим образом:
#include "TextQuery.h"
int main()
{
TextQuery tq;
tq.build_up_text();
tq.query_text();
}
build_text_map() - это слегка видоизмененная функция-член doit() из главы 6. Ее основная задача - построить отображение для хранения позиций всех значимых слов текста. (Если помните, мы не храним семантически нейтральные слова типа союзов if, and, but и т.д. Кроме того, мы заменяем заглавные буквы на строчные и устраняем суффиксы, обозначающие множественное число: например, testifies преобразуется в testify, а marches в march.) С каждым словом ассоциируется вектор позиций, в котором хранятся номера строки и колонки каждого вхождения слова в текст.
query_text() принимает запросы пользователя и преобразует их во внутреннюю форму на основе иерархии классов Query с одиночным наследованием и динамическим связыванием. Внутреннее представление запроса применяется к отображению слов на вектор позиций, построенному в build_text_map(). Ответом на запрос будет множество строк текстового файла, удовлетворяющих заданному критерию:
Enter a query - please separate each item by a space.
Terminate query (or session) with a dot( . ).
== fiery && ( bird || shyly )
fiery ( 1 ) lines match
bird ( 1 ) lines match
shyly ( 1 ) lines match
( bird || shyly ) ( 2 ) lines match
fiery && ( bird || shyly ) ( 1 ) lines match
Requested query: fiery && ( bird || shyly )
( 3 ) like a fiery bird in flight. A beautiful fiery bird, he tells her.
В нашей системе мы выбрали следующий язык запросов:
1. одиночное слово, например Alice или untamed. Выводятся все строки, в которых оно встречается, причем каждой строке предшествует ее номер, заключенный в скобки. (Строки печатаются в порядке возрастания номеров). Например:
== daddy
daddy ( 3 ) lines match
Requested query: daddy
( 1 ) Alice Emma has long flowing red hair. Her Daddy says
( 4 ) magical but untamed. "Daddy, shush, there is no such thing,"
( 6 ) Shyly, she asks, "I mean, Daddy, is there?"
1. запрос "НЕ", формулируемый с помощью оператора !. Выводятся все строки, где не встречается указанное слово. Например, так формулируется отрицание запроса 1:
== ! daddy
daddy ( 3 ) lines match
! daddy ( 3 ) lines match
Requested query: ! daddy
( 2 ) when the wind blows through her hair, it looks almost alive,
( 3 ) like a fiery bird in flight. A beautiful fiery bird, he tells her,
( 5 ) she tells him, at the same time wanting him to tell her more.
запрос "ИЛИ", формулируемый с помощью оператора ||. Выводятся все строки, в которых встречается хотя бы одно из двух указанных слов:
== fiery || untamed
fiery ( 1 ) lines match
untamed ( 1 ) lines match
fiery || untamed ( 2 ) lines match
Requested query: fiery || untamed
( 3 ) like a fiery bird in flight. A beautiful fiery bird, he tells her,
( 4 ) magical but untamed. "Daddy, shush, there is no such thing,"
запрос "И", формулируемый с помощью оператора &&. Выводятся все строки, где оба указанных слова встречаются, причем располагаются рядом. Сюда входит и случай, когда одно слово является последним в строке, а другое - первым в следующей:
== untamed && Daddy
untamed ( 1 ) lines match
daddy ( 3 ) lines match
untamed && daddy ( 1 ) lines match
Requested query: untamed && daddy
( 4 ) magical but untamed. "Daddy, shush, there is no such thing,"
Эти элементы можно комбинировать:
fiery && bird || shyly
Однако обработка производится слева направо, и все элементы имеют одинаковые приоритеты. Поэтому наш составной запрос интерпретируется как fiery bird ИЛИ shyly, а не как fiery bird ИЛИ fiery shyly:
== fiery && bird || shyly
fiery ( 1 ) lines match
bird ( 1 ) lines match
fiery && bird ( 1 ) lines match
shyly ( 1 ) lines match
fiery && bird || shyly ( 2 ) lines match
Requested query: fiery && bird || shyly
( 3 ) like a fiery bird in flight. A beautiful fiery bird, he tells her,
( 6 ) Shyly, she asks, "I mean, Daddy, is there?"
Чтобы можно было группировать части запроса, наша система должна поддерживать скобки. Например:
fiery && (bird || shyly)
выдает все вхождения fiery bird или fiery shyly1. Результат исполнения этого запроса приведен в начале данного раздела. Кроме того, система не должна многократно отображать одну и ту же строку.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
2. Наследование
2. Наследование Процесс, с помощью которого один тип наследует характеристики другого типа, называется наследованием. Наследник называется порожденным (дочерним) типом, а тип, которому наследует дочерний тип, называется порождающим (родительским) типом.Ранее известные
Проектирование классов и наследование
Проектирование классов и наследование Наиболее важный аспект разработки программного обеспечения — ясно понимать, что именно вы пытаетесь построить. — Бьярн Страуструп (Bjarne Stroustrup) Какого вида классы предпочитает разрабатывать и строить ваша команда? Почему?Интересно,
Правило 34: Различайте наследование интерфейса и наследование реализации
Правило 34: Различайте наследование интерфейса и наследование реализации Внешне простая идея открытого наследования при ближайшем рассмотрении оказывается состоящей из двух различных частей: наследования интерфейса функций и наследования их реализации. Различие
1.1.2. Наследование
1.1.2. Наследование Мы подходим к одной из самых сильных сторон ООП — наследованию. Наследование —- это механизм, позволяющий расширять ранее определенную сущность путем добавления новых возможностей. Короче говоря, наследование - это способ повторного использования
11.1.5. Наследование суперклассу
11.1.5. Наследование суперклассу Можно унаследовать класс, воспользовавшись символом <:class Boojum < Snark # ...endЭто объявление говорит, что класс Boojum является подклассом класса Snark или — что то же самое — класс Snark является суперклассом класса Boojum. Всем известно, что каждый буюм
Наследование
Наследование Следующим принципом ООП является наследование, означающее способность языка обеспечить построение определений новых классов на основе определений существующих классов. В сущности, наследование позволяет расширить возможности поведения базового класса
Наследование
Наследование Пожалуй, самая важная возможность, предоставляемая программисту средствами языка Си++, заключается в механизме наследования. Вы можете наследовать от определенных ранее классов новые производные классы. Класс, от которого происходит наследование,
Единичное наследование
Единичное наследование В случае единичного наследования порожденный класс наследуется только от одного базового класса. Рисунок 1.1 отражает единичное наследование классов. Единичное наследование является наиболее распространенным методом наследования. Библиотека
Множественное наследование
Множественное наследование Множественное наследование выполняется подобно единичному наследованию. В отличие от единичного наследования у порожденного класса может быть несколько базовых классов. На рисунке 1.2 представлен пример множественного наследования классов.
Наследование
Наследование Класс может быть унаследован от другого класса. Класс, от которого наследуют, называют базовым классом (надклассом, предком), а класс, который наследуется, называется производным классом (подклассом, потомком). При наследовании все поля, методы и свойства
Наследование конструкторов
Наследование конструкторов Правила наследования конструкторов - достаточно сложные. В разных языках программирования приняты разные решения на этот счет. В частности, в Delphi Object Pascal все конструкторы наследуются. В .NET, напротив, конструкторы не наследуются. Причина такого
Наследование инварианта
Наследование инварианта Хотелось бы указать инвариант класса RECTANGLE, который говорил бы, что число сторон прямоугольника равно четырем и что длины сторон последовательно равны side1, side2, side1 и side2.У класса POLYGON также имеется инвариант, который применим и к его
Наследование и конструкторы
Наследование и конструкторы Ранее не показанная процедура создания (конструктор) для класса POLYGON может иметь видmake_polygon (vl: LINKED_LIST [POINT]) is-- Создание по вершинам из vl.requirevl.count >= 3do...Инициализация представления многоугольника по элементам из vl ...ensure-- vertices и vl состоят из
Наследование и децентрализация
Наследование и децентрализация Имея динамическое связывание, можно создавать децентрализованные архитектуры ПО, необходимые для достижения целей повторного использования и расширяемости. Сравним ОО-подход, при котором самодостаточные классы предоставляют свои
У14.4 Наследование без классов
У14.4 Наследование без классов В этой лекции были представлены два взгляда на наследование: будучи модулем, класс-наследник предлагает службы своего родителя плюс еще некоторые, будучи типом, он реализует отношение "является" (каждый экземпляр наследника является также
26. Наследование
26. Наследование Наследование – это процесс порождения новых типов-потомков от существующих типов-родителей, при этом потомок получает (наследует) от родителя все его поля и методы.Тип-потомок, при этом, называется наследником или порожденным (дочерним) типом. А тип,