Основные концепции ООП — Информатика. Шпоры | iFREEstore

Основные концепции ООП

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

Основные шаги разработки программы, предусмотренные данной методологией:

• определить проблему;

• развить неформальную стратегию, представляющую общую последовательность шагов, удовлетворяющую требованиям к будущей программе;

• формализовать стратегию

• идентифицировать объекты и их атрибуты;

• идентифицировать операции;

• установить интерфейсы;

• реализовать операции.

Большинство современных языков и систем программирования развивается в направлении все большего использования объектной методологии в создании программ. Характерными примерами являются универсальные языки Паскаль, СИ и даже Бейсик, в современных версиях которых появились средства объектно-ориентированного программирования. Так, начиная с версии 5.5, Турбо-Паскаль охватывает метод проектирования программ на основе объектно-ориентированного программирования.

Основы объектного программирования в системе турбо-паскаль

Объект в ТурбоПаскале - это структура данных, содержащая поля данных различных типов и заголовки методов и обобщающая структуру «Запись» (record). Синтаксис описания объекта:

<ИмяПотомка>=оbjесt<ИмяПредка> поле;

поле; … метод; … метод; end;

В отличие от записи полями объекта могут быть, кроме данных, еще и методы, обрабатывающие эти данные

Метод - это процедура или функция, объявленные внутри описания объекта. Синтаксис описания метода:

procedure <Заголовок>(<Параметр1>, <Параметр2>:integer),

Метод имеет доступ к полям данных объекта, не требуя передачи их ему в виде параметров

Объявление метода внутри объявления объектного типа содержит только заголовок. Тело метода определяется вне объявления объекта. Его заголовок должен содержать имя объекта, которому принадлежит метод. Например:

procedure <ТипОбъекта.Метод>

(<Параметр1>, <Параметр2> : integer);

Begin … … еnd;{Метод}

Методы подразделяют на статические и виртуальные. Виртуальный метод отличается от статического тем. что реализующий его код подсоединяется к исполняемой программе не в процессе компиляции, а в процессе выполнения,

Смысл объектно-ориентированного программирования заключается в работе с полями объекта через его методы.

Полиморфизм. Предположим, надо создать объект «кружок». Очевидно, что новый объект должен иметь предком объект Point, обладая всеми его свойствами, кроме того. быть больше по размеру. Однако, ясно, что «высветить» точку и закрашенную окружность не удастся одними и теми же командами. Турбо-Паскаль разрешает сохранить потомку имя родительского метода, «перекрывая» его. Чтобы перекрыть родительский метод, надо просто задать его с тем же именем, но с другим телом (кодом) и, если необходимо, с другим набором параметров. Такой метод делается виртуальным и к его объявлению добавляется слово virtual. Применение виртуальных методов налагает ограничения на процедуры инициализации, которые должны записываться с зарезервированным словом constructor и иметь общее имя Init

Каждый отдельный экземпляр объекта должен инициализироваться с помощью отдельного вызова конструктора

Для очистки и удаления динамически распределенных объектов существует специальная процедура destructorDone.

Деструктор комбинирует шаг освобождения памяти в «куче» с некоторыми другими задачами. Метод деструктора может быть пустыу), поскольку работу выполняет не только код тела, но и код, генерируемый Турбо-Паскалем в ответ на зарезервированное слово destructor.

всесторонней реализации сложных математических моделей, не допускающих аналитического исследования, с другой - возникли принципиально новые направления, и прежде всего - имитационное моделирование.

ИМИТАЦИОННОЕ МОДЕЛИРОВАНИЕ ДИНАМИКИ ПОПУЛЯЦИЙ

Выше мы обсудили несколько классических математических моделей в экологии. Известно и немало других, которые можно найти в книгах и в статьях научно-популярных журналов.

Использование математических моделей, основанных на дифференциальных уравнениях или их дискретных аналогах, далеко не единственный путь в компьютерном моделировании динамики популяций. Другую интересную группу составляют чисто стохастические модели или динамические модели с элементами стохастичности. Опишем две возможные модели такого класса: одну - без подробностей, которые рекомендуем продумать самостоятельно, другую - во всех деталях, включая реализующую ее программу.

Первая модель. Две популяции находятся в соотношении «хищник - жертва», описанном выше, но модель совершенно иная. На некотором клетчатом поле (которое наглядно - все или по частям - изображается на дисплее) находятся волки (несколько) и зайцы (много). Зайцы совершают беспорядочные перемещения, длины и направления которых - случайные величины, подчиняющиеся некоторому закону распределения вероятностей, а каждый волк в каждое мгновение ориентируется на ближайшего зайца и может совершать ограниченные прыжки. Если волк в течение некоторого, заранее определенного, промежутка времени остается без добычи (т.е. не попадает в клетку, где находится заяц), то он погибает. Зайцы и волки через определенные моменты размножаются, например, каждый второй заяц приносит двух потомков, каждый второй волк приносит одного потомка, причем скорость размножения волков в два раза ниже, чем зайцев. Все это может красочно изображаться на экране, состояние которого меняется через фиксированные моменты времени.

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

Возможны и пограничные - динамико-стохастические модели. Например, в уравнениях Лотки - Вольтерры один из параметров - случайная величина с известным законом распределения. Самостоятельные размышления над такими задачами, даже лишь над их постановкой, очень полезны.

Вторая модель, которую опишем во всех деталях, предложена Д.Конвейем -имитационная модель роста, распада и различных изменений в популяции живых организмов, известная под названием «Жизнь».

Для построения алгоритма игры рассмотрим квадратное поле из n+1 столбцов и строк с обычной нумерацией от 0 до n, рис. 7.48. Крайние граничные столбцы и строки для удобства определим как «мертвую зону», они играют лишь вспомогательную роль.

Для любой внутренней клетки поля с координатами (i, j) можто определить 8 соседей. Если клетка «живая», ее закрашиваем, если клетка «мертвая», она пустая.

Зададим правила игры. Если клетка (i, j) «живая» и в окружении более трех «живых» клеток, она погибает (от перенаселения). «Живая» клетка также

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

В системе с генерацией имеются специальные программы, анализирующие макрокоманду, которые определяют, какую функцию необходимо выполнить и формируют необходимую последовательность команд, реализующих данную функцию.

Обе указанных системы используют трансляторы с ЯСК и набор макрокоманд, которые также являются операторами автокода. Развитые автокоды получили название Ассемблеры. Сервисные программы и пр., как правило, составлены на языках типа Ассемблер.

Макрос. Язык, являющийся средством для замены последовательности символов описывающих выполнение требуемых действий ЭВМ на более сжатую форму - называется Макрос(средство замены). В основном, Макрос предназначен для того, чтобы сократить запись исходной программы. Компонент программного обеспечения, обеспечивающий функционирование макросов, называется макропроцессором. На макропроцессор поступает макроопределяющий и исходный текст. Реакция макропроцессора на вызов-выдача выходного текста. Макрос одинаково может работать, как с программами, так и с данными.

Язык ассе́мблера (англ. assembly language) — машинно-ориентированный язык низкого уровня с командами, обычно соответствующими командам машины, который может обеспечить дополнительные возможности вроде макрокоманд; автокод, расширенный конструкциями языков программирования высокого уровня, такими как выражения, макрокоманды, средства обеспечения модульности программ.

Исторически, если первым поколением языков программирования считать машинные коды, то язык ассемблера можно рассматривать как второе поколение языков программирования. Недостатки языка ассемблера, сложность разработки на нём больших программных комплексов привели к появлению языков третьего поколения - языков программирования высокого уровня (таких как Фортран, Лисп, Кобол, Паскаль, Си и др.). Именно языки программирования высокого уровня и их наследники в основном используются в настоящее время в индустрии информационных технологий. Однако, языки ассемблера сохраняют свою нишу, обусловленную их уникальными преимуществами в части эффективности и возможности полного использования специфических средств конкретной платформы.

На языке ассемблера пишут программы или их фрагменты в тех случаях, когда критически важны:

быстродействие (драйверы, игры); объём используемой памяти (загрузочные секторы, встраиваемое (англ. embedded) программное обеспечение, программы для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, программные защиты).

С использованием программирования на языке ассемблера производятся:

Оптимизация критичных к скорости участков программ в программах на языках высокого уровня, таких как C++ или Pascal. Это особенно актуально для игровых приставок, имеющих фиксированную производительность, и для мультимедийных кодеков, которые стремятся делать менее ресурсоёмкими и более быстрыми.

Создание операционных систем (ОС) или их компонентов. В настоящее время подавляющее большинство ОС пишут на более высокоуровневых языках (в

время падает на землю. Напомним элементарное решение этой задачи. Разложим скорость на горизонтальную и вертикальную составляющие:

Поскольку движение по вертикали происходит под действием постоянной силы тяжести, то оно является равнозамедленным до достижения верхней точки на траектории и равноускоренным - после нее; движение же по горизонтали является равномерным. Из формул равноускоренного движения vy = v -gt; раз в верхней точке vy = 0, то время достижения верхней точки на траектории

Высота этой точки

Полное время движения до падения на землю 2; за это время, двигаясь равномерно вдоль оси х со скоростью v, тело пройдет путь

Для нахождения траектории достаточно из текущих значений x и у исключить t:

следовательно,

(7.11)

Уравнение (7.11) - уравнение параболы.

Полученные формулы могут, в частности, послужить для тестирования будущей компьютерной программы. При достаточно большой начальной скорости сопротивление воздуха может значительно изменить характер движения. Прежде чем выписывать уравнения, вновь оценим, какая из составляющих силы сопротивления - линейная или квадратичная по скорости - дает больший вклад в эту силу, и нельзя ли одной из этих составляющих пренебречь. Оценку проведем для шарика; по порядку величины оценка не зависит от формы тела. Итак, шарик радиусом r ≈ 0,1 м, движущийся со скоростью ~ 1 м/с, испытывает в воздухе линейную (стоксову) силу сопротивления

и квадратичную силу сопротивления

Величины F1 и F2 сопоставимые (как принято говорить, «одного порядка», так как они различаются менее, чем в 5 раз). При увеличении размера тела F2 растет быстрее, чем F1 (F1 ~ r, F2 ~ r2), при увеличении скорости F2 также растет быстрее, чем F1 (F1 ~ v, F2 ~ v2). Таким образом, если мы моделируем движение брошенного мяча, камня, то необходимо в уравнениях удерживать

изучаемого движения есть множество вариантов, определяемых наборами значений параметров, входящих в уравнения (7.12), (7.13) или являющихся для них начальными условиями: k1, k2, m, g, v0, а. После обезразмеривания переменных появляются безразмерные комбинации параметров - в данном случае a, b, α - фактически определяющие характер движения. Если мы изучаем два разных движения с разными размерными параметрами, но такие, что а, b и α одинаковы, то движения будут качественно одинаковы. Число таких комбинаций обычно меньше числа размерных параметров (в данном случае вдвое), что также создает удобство при полном численном исследовании всевозможных ситуаций, связанных с этим процессом. Наконец, как уже отмечалось, величины Vx, Vy, X, Y, τ физически легче интерпретировать, чем их размерные аналоги, так как они измеряются относительно величин, смысл которых очевиден. Прежде чем предпринимать численное моделирование, отметим, что при учете лишь линейной составляющей силы сопротивления модель допускает аналитическое решение. Система уравнений (7.14) при b = 0 достаточно элементарно интегрируется и результаты таковы:

(7.14)

Исключая из двух последних формул время, получаем уравнение траектории:

Заметим, что эта формула не из тех, которые привычно визуализируются, например, по сравнению с совершенно отчетливой формулой (7.11), и здесь компьютер может быть полезен в том, чтобы составить ясное представление о влиянии линейной части силы сопротивления на изучаемое движение

Рис. 7.8. Семейство траекторий при α = 45°

и значениях α, равных 0,01; 0,1; 1 и 10 (кривые - справа налево)

На рис. 7.8 приведены траектории четырех движений с разными значениями параметра α, характеризующего трение. Видно, как сильно оно влияет на движение - его форму, расстояния по вертикали и горизонтали. Общее исследование при произвольных значениях а и b поможет выполнить приведенная ниже программа.

Фактически представлены две программы: при активизации первого или второго блока. В первом случае она выдает результаты численного моделирования в виде таблицы значений безразмерных скоростей и координат при фиксированном наборе параметров а, b и α, значения которых устанавливаются в разделе определения констант. При взятии в фигурные скобки первого блока и активизации второго (т.е. снятия фигурных скобок)

Рис. 7.10. Графики зависимости V(τ) и Y(X) при решении задачи о полете тела, брошенного под углом к горизонту, без учета сопротивления воздуха (скорость изменяется от 1 и вновь достигает значения 1; траектория - парабола) и с учетом сопротивления воздуха (конечная скорость меньше 1, и траектория - далеко не парабола) (а = 1, b = 1)

С помощью приведенной выше программы можно провести полное исследование модели в широком диапазоне значений параметров и составить качественное представление об их влиянии на изучаемое движение. Некоторые результаты иллюстрируются рис. 7.11,7.12.

Рис. 7.11. Влияние параметра а на движение тела, брошенного под углом к горизонту, при b = 0,1 (слева) и при b = 1 (справа); α = π/4 (а = 0,01; 0,1; 1; 10; кривые на рисунках соответственно располагаются справа налево)

Рис. 7.12. Влияние параметра b на движение тела, брошенного под углом к горизонту, при a = 0,1 (слева) и при а = 1 (справа); α = π/4 (b = 0,01; 0,1; 1; 10; кривые на рисунках соответственно располагаются справа налево)

123

vara: array [0..100] of integer;

Сначала мы, как и обычно, указываем название нашего массива. Затем, после "array", мы указываем диапазон индексов в массиве, т.е. в данном случае мы создали 101 элементов массива с заданными индексами. И затем естественно указываем тип элементов массива, а именно пишем после "of" тип "integer", т.е. элементы массива целочисленные.

Теперь как же обратиться к элементам массива непосредственно из кода, т.е. работать с этими элементами как с обыкновенными переменными? Делается это предельно просто. Обратиться к любому элементу массива можно следующим образом:

123

a[1]:=100;a[99]:=200;

В квадратных скобках мы указываем индекс самого элемента массива. Очень важно учитывать, что введенный индекс, по которому мы хотим обратиться к элементу массива, должен быть в указанном при объявлении массива диапазоне, иначе программа во время своей работы выдаст нам ошибку. Также, в качестве индекса может выступать и другая любая переменная типа integer (а также и различные примитивные математические операции), например так:

123

a[i]:=100;a[i+10]:=200;

В Java массивы являются объектами. Это значит, что имя, которое даётся каждому массиву, лишь указывает на адрес какого-то фрагмента данных в памяти. Кроме адреса в этой переменной ничего не хранится. Индекс массива, фактически, указывает на то, насколько надо отступить от начального элемента массива в памяти, чтоб добраться до нужного элемента.

Чтобы создать массив надо объявить для него подходящее имя, а затем с этим именем связать нужный фрагмент памяти, где и будут друг за другом храниться значения элементов массива.

Возможные следующие варианты объявления массива:

тип[] имя; тип  имя[];

Где тип — это тип элементов массива, а имя — уникальный (незанятый другими переменными или объектами в этой части программы) идентификатор, начинающийся с буквы.

Примеры:

int[] a; double[] ar1; double  ar2[];

В примере мы объявили имена для трёх массивов. С первом именем a сможет быть далее связан массив из элементов типа int, а с именами ar1 и ar2 далее смогут быть связаны массивы из вещественных чисел (типа double). Пока мы не создали массивы, а только подготовили имена для них.

Теперь создать (или как ещё говорят инициализировать) массивы можно следующим образом:

a = new int[10]; // массив  из 10 элементов типа intint n = 5; ar1 =  new double[n]; // Массив из 5 элементов doublear2 = {3.14, 2.71, 0, -2.5, 99.123}; // Массив из 6 элементов типа double

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

применения в данном алгоритме, можно свести число парметров к одному (какому?), а не двум.

Сортировка вставками

Второй метод называется метод вставок., т.к. на j-ом этапе мы "вставляем" j-ый элемент M[j] в нужную позицию среди элементов M[1], M[2],. . ., M[j-1], которые уже упорядочены. После этой вставки первые j элементов массива M будут упорядочены.Сказанное можно записать следующим образом:

нц для j от 2 до N    переместить M[j] на позицию i <= j такую, что         M[j] < M[k] для i<= k < j и         либо M[j] >= M[i-1], либо i=1кц

Чтобы сделать процесс перемещения элемента M[j], более простым, полезно воспользоваться барьером: ввести "фиктивный" элемент M[0], чье значение будет заведомо меньше значения любого из "реальных"элементов массива (как это можно сделать?). Мы обозначим это значение через —оо.

Если барьер не использовать, то перед вставкой M[j], в позицию i-1 надо проверить, не будет ли i=1. Если нет, тогда сравнить M[j] ( который в этот момент будет находиться в позиции i) с элементом M[i-1].

Описанный алгоритм имеет следующий вид:

begin   M[0] := -oo;   for j:=2 to N do    begin       i := j;         while M[i] < M[i-1] do          begin               swap(M[i],M[i-1]);              i := i-1          end    end end;

Процедура swap нам уже встречалась.

Сортировка посредством выбора

Идея сортировки с помощью выбора не сложнее двух предыдущих. На j-ом этапе выбирается элемент наименьший среди M[j], M[j+1],. . ., M[N](см. процедуру FindMin) и меняется местами с элементом M[j]. В результате после j-го этапа все элементы M[j], M[j+1],. . ., M[N]будут упорядочены.

Сказанное можно описать следующим образом:

нц для j от 1 до N-1    выбрать среди M[j],. . ., M[N] наименьший элемент и    поменять его местами с M[j]кц

Более точно:

begin

for j:=1 to N-1 do

begin

FindMin(j, i);

swap(M[j],M[i])

end

end;

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

знает (мария, английский).

знает (иван, английский).

«Знает Иван то (х), что знает Мария?»

знает (иван, Х) :- знает (мария, Х).

констатирующая часть условная часть

Тело правила может содержать 1, 2 или несколько предикатов, объединенных между собой операцией логического умножения. В этом случае говорят, что тело правила содержит конъюнкцию целей. Например:

«Алисе нравиться кто-то, если кому-то нравятся книги и кому-то нравится музыка»

нравится (алиса, Y) :- нравится (Y, книга), нравится (Y, музыка).

Чем больше аргументов, входящих в правило, являются переменными, тем большей общностью правило обладает.

Истинность правила зависит от некоторых условий (целей). Если все цели в теле правила истинны, то и все правило считается истинным. Из совокупности фактов и правил об объектах и отношениях между ними строится база знаний. Например:

знает (мария, английский).

знает (иван, английский).

«Знает Иван то (х), что знает Мария?»

знает (иван, Х) :- знает (мария, Х).

знает (иван, Х) :- знает (мария, Х).

студент (олег).

студентка (мария).

профессор (петр_петрович).

учится (Х) :- студент (Х).

учится (Х) :- студентка (Х).

преподает (Х) :- профессор (Х).

Вопрос – это отправная точка логического вывода, происходящего при выполнении программ. Вопрос в Прологе называется целью.

Рассмотрим два вида вопросов (целей):

сущность вопроса в том, чтобы подтвердить справедливость фактов. В результате получится ответ «ДА», если факт содержится в базе знаний или выводится с использованием фактов и правил базы знаний. В противном случае получается ответ «НЕТ».

? – знает (иван, английский). - ДА

сущность вопроса состоит в перечислении всех значений переменной указанной в запросе, удовлетворяющему фактам и правилам базы знаний.

? – знает (иван, Х). – английский, алгебра, информатика, история

? – знает (Х, алгебра), учится (Х). – х – мария

Факт — это сообщение (информация) о конкретном событии, о свойстве конкретного объекта, о его связи с другими объектами. Например, фактами являются следующие утверждения:

сосна — хвойное дерево;

Колумб открыл Америку в 1492 году;

плотность воды равна 1 г/см3;

царь Соломон — сын царя Давида;

Лев Толстой — русский писатель.

Правило — это утверждение, обладающее большей общностью, чем факт. Правила определяют одни понятия через другие, устанавливают взаимосвязь

Вот вопрос первого типа к БЗ «Родственники», сформулированный в разговорной форме:

Является ли Лев отцом Андрею?

На Прологе соответствующая цель пишется так:

? отец («Лев», «Андрей»).

Ответ будет положительный: «да», поскольку такой факт содержится в базе знаний. Ответ на следующий вопрос:

?внук («Алексей», «Лев»)

будет также положительный. При этом система Пролог проанализирует правила и факты базы знаний и, установив искомую связь, выведет ответ «да». На вопрос же

? сын («Дмитрий», «Андрей»),

то есть является ли Дмитрий сыном Андрея, будет получен ответ «нет».

А теперь сформулируем цели второго типа. Пусть, например, нам требуется получить список имен всех детей Петра. Вопрос запишется так:

? отец («Петр», Х).

Пролог выдаст ответ в следующем виде:

X = Михаил;

X= Дмитрий.

Тот же самый вопрос можно сформулировать и иначе:

? сын (Х, «Петр»).

Ответ будет тот же, что и выше.

Поскольку имя переменной может быть многосимвольным (главное, чтобы начиналось с прописной буквы), то этим можно воспользоваться для получения более наглядного ответа. По следующему запросу будут выведены все пары имен отец-сын:

? отец (Отец, Сын).

Результат:

Отец=Лев, Сын=Андрей;

Отец=Лев, Сын=Петр;

Отец=Андрей, Сын=Алексей;

Отец=Петр, Сын=Михаил;

Отец=Петр, Сын=Дмитрий.

Конъюнкция используется не только в формулировке правил, но и при записи целей. Предположим, нужно узнать, действительно ли Лев имеет двух сыновей по имени Андрей и Петр? Это запрос первого типа, дающий ответ «да» или «нет».

? отец («Лев», «Андрей»), отец («Лев», «Петр»).

Ответ будет положительный.

Другой пример. Требуется перечислить имена внуков Льва, которые являются сыновьями Петра:

? внук (Х, «Лев» ), сын (Х, «Петр» ).

Ответ будет:

X = Михаил; X = Дмитрий.

А теперь обратимся к БЗ с запросом:

? брат (X,Y),

то есть мы хотим перечислить все пары братьев. Ответ будет таким:

Х = Андрей, Y = Петр; Х = Петр, Y = Андрей; Х = Дмитрий, Y = Михаил;

Х = Михаил, Y = Дмитрий.

Каждая пара повторяется дважды в разном порядке. Чтобы избавиться от повторений, цель можно сформулировать так:

? брат (X,Y), X<Y.

Ответом будет:

X = Андрей, Y = Петр;

Х = Дмитрий, Y = Михаил.

2) из рекурсивного правила, определяющего операцию над списком, состоящим из головы и хвоста ( в голове правила), через операцию над хвостом (в подцели).

Пример I: определение числа элементов в списке.

сколько ([], 0).

сколько ([А|В], N) :- сколько (В, М), N is M+1.

?- сколько ([саша, игорь, лена]), X).

Ответ: Х=3.

Пример 2: принадлежность элемента списку.

принадлежит (X, [X | Y]).

принадлежит (X, [A |Y ]) : - принадлежит (X,Y).

?-принадлежит (4,(1,3,4,9]).

Ответ:да.

Данная программа имеет очень простой декларативный смысл: элемент принадлежит списку, если он является его головой или принадлежит хвосту списка.

Пример 3: соединение двух списков.

Эту задачу можно описать с помощью следующих предикатов:

а) ограничение рекурсии состоит в том, что если к пустому списку [ ] добавить список Р, то в результате получится Р;

б) рекурсия состоит в том, что можно список Р добавить к концу списка [X|Y], если Р будет добавлен к хвосту Y и затем присоединен к голове Х (при этом получается список [Х|Т]).

присоединить([ ], Р, Р).

присоединить([XIY], Р, [X | Т]):-присоединить(Y, Р, Т).

? присоединить(L,[джим.R],(джек,бил,джим,тим,джим,боб]).

Ответ:

L=[джек,бил]. К=[тим джим,боб]. L=[джек,бил,джим,тим]. R=[бoб].

Существует традиция использовать для обозначения предиката слияния двух списков предикативный символ append (по-английски -добавить).

В некоторых случаях постановки вопросов к такого рода программам приходится использовать отсечение (!).

Программа 125

append([ ], L, L).

append([A I B] , C, [A | D]):- append(B, C, D).

?-append(X,Y,[1,2]).

Ответ:

X=[]

Y=[l,2]

X=[l]

Y=[2]

X=[l,2]

Y=[].

Если же заменить первое предложение на append([ ], 1,1):- !. и задать тот же вопрос, то получится правильный ответ:

Х=[]

Y=[l,2].

Пример 4. удаление элементов из списка.

Программа 126 аналогична проверке принадлежности элемента списку, но требует уже трехарного предиката, один аргумент которого указывает удаляемый элемент, второй аргумент-исходный список и третий - список-результат.

Программа 126

удал (X. [X I Y], Y) : - !.

что достигается, так называемым, поздним связыванием. Это дает возможность строить иерархию объектов с одинаковыми названиями методов, реализуемыми, однако, различными кодами.

Синтаксис виртуального метода:

procedure <Метод> (<Параметр1>, <Параметр2> : integer): virtual;

Кроме обычных процедур и функций, ТурбоПаскаль 6.0 реализует два специальных типа методов: конструктор и деструктор.

Конструктор - это специальный метод, инициализирующий объект, содержащий виртуальные методы, он объявляется специально зарезервированным словом constructor. Конструктор инициализирует объект путем установления связи между объектом и специальной таблицей виртуальных методов, содержащей адреса кодов, реализующих виртуальные методы. Конструктор может также использоваться для инициализации полей данных объекта.

Деструктор - это специальный метод, освобождающий память «кучи» от динамических объектов. Он объявляется с использованием специально зарезервированного слова destructor.

Основными отличительными свойствами объекта являются

• инкапсуляция - объединение записей с процедурами и функциями, работающими с этими записями;

• наследование - задание объекта, затем использование его для построения иерархии порожденных объектов с наследованием доступа каждого из порожденных объектов к коду и данным предка;

• полиморфизм - задание одного имени действию, которое передается вверх и вниз по иерархии объектов с реализацией этого действия способом, соответствующим каждому объекту в иерархии.

Рассмотрим смысл каждого из перечисленных свойств на примере построения на экране дисплея точек разных цветов (звездного неба).

Инкапсуляция. Основой решения задачи является задание положения (позиции) отдельной точки на экране, описываемого координатами Х и Y. Для задания координат подходит тип «запись»:

Pozition = record

X, Y : integer;

end;

Далее может быть необходимо задать значения координат (такая процедура носит название инициализации). Создадим соответствующую процедуру:

procedure Init(CoordX, CoordY : integer);

begin

X : = CoordX; Y : = CoordY;

end;

Затем потребуется знание фактических значений координат. Для этого вводим две функции:

function GetX : integer;

begin

GetX: = X; end;

function GetY: integer; begin GetY: = Y;end;

По нашему замыслу процедура Init и функции GetX и GetY должны работать только с полями записи Pozition.

Введение объектов позволяет зафиксировать это положение, объявив и поля, и действия над ними в единой конструкции:

Pozition = object

X, Y: integer;

procedure Init(CoordX, CoordY : integer);

function GetX : integer; function GetY : integer; end;

Процедура Init и функции GetX и GetY являются методами объекта Pozition.

Для инициализации экземпляра типа Pozition достаточно вызвать его метод,

погибает, если в окружении менее двух «живых» клеток (от одиночества). «Мертвая» клетка оживает, если вокруг нее имеются три «живые» клетки. Для удобства введем двумерный массив А[0..п, 0..п], элементы которого принимают значение 0, если соответствующая клетка пустая, и 1, если клетка «живая». Тогда алгоритм определения состояния клетки с координатой (i,j) можно определить следующим образом:

S := A[I-1, J-1] + A[I-1, J] + A[I-1, J+1] + A[I+1, J-1]

+ А[I+1, J] + A[I+1, J+l] + A[I, J+l] + А[1, J-1];

If (A[I, J] = 1) And ((S > 3) Or (S < 2); Then B(I, J] := 0;

If (A[I, J] = 0) And (S = 3) Then B[I, J] := 1;

Здесь массив В [0..п, 0..п] определяет координаты поля на следующем этапе. Для всех внутренних клеток от i = 1 до n - 1 и j = 1 до n - 1 справедливо сказанное выше. Отметим, что последующие поколения определяются аналогично, лишь стоит осуществить процедуру переприсваивания

For I := 1 То N-l DO For J := 1 To N-l Do A[I, J] := B[I, J] ;

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

For I := 1 То К Do

Begin Kl := Random(N-l); K2 := Random(N-l)+1; A[K1, K2] := 1 End;

Поставим несколько вопросов: какие конфигурации исчезают с течением времени и как быстро? какие структуры могут существовать бесконечно? каковы законы организации структур, их взаимодействия? Перед попыткой ответить на эти вопросы читателю будет полезно поэкспериментировать самому. Предварительно отметим лишь некоторые структуры (рис. 7.49-7.50).

Существуют структуры, которые повторяют себя через 1, 2, ...,п временных шагов, их называют циклами «-n» (см. рис. 7.50).

Но наиболее интересны движущиеся структуры - «планеры», «корабли», «паровозы», их столкновения, «аннигиляции» и зарождение новых структур.

Представляет интерес модель игры в одномерном случае. Здесь имеется один ряд клеток. В некоторых нз них задаем «жизнь». Требуется изучить эволюцию клеток, если заданы правила их существования и зарождения.

Определим сумму значений пяти соседних клеток (самой клетки и двух ближайших к ней слева и справа). На следующем шаге в

основном на Си — языке высокого уровня, который специально был создан для написания одной из первых версий UNIX). Аппаратно зависимые участки кода, такие как загрузчик ОС, уровень абстрагирования от аппаратного обеспечения (hardware abstraction layer) и ядро, часто пишутся на языке ассемблера. Фактически, ассемблерного кода в ядрах Windows или Linux совсем немного, поскольку авторы стремятся обеспечить переносимость и надёжность, но, тем не менее, он там присутствует. Некоторые любительские ОС, такие как MenuetOS и KolibriOS, целиком написаны на языке ассемблера. При этом MenuetOS помещается на дискету и содержит графический многооконный интерфейс.

Программирование микроконтроллеров (МК) и других встраиваемых процессоров. По мнению профессора Таненбаума, развитие МК повторяет историческое развитие компьютеров новейшего времени. Сейчас (2013 г.) для программирования МК весьма часто применяют язык ассемблера (хотя и в этой области широкое распространение получают языки вроде Си). В МК приходится перемещать отдельные байты и биты между различными ячейками памяти. Программирование МК весьма важно, так как, по мнению Таненбаума, в автомобиле и квартире современного цивилизованного человека в среднем содержится 50 микроконтроллеров.

Создание драйверов. Драйверы (или их некоторые программные модули) программируют на языке ассемблера. Хотя, в настоящее время, драйверы также стремятся писать на языках высокого уровня (на высокоуровневом языке много проще написать надёжный драйвер), в связи с повышенными требованиями к надёжности, и достаточной производительностью современных процессоров (быстродействие обеспечивает временно́е согласование процессов в устройстве и процессоре) и достаточным совершенством компиляторов с языков высокого уровня (отсутствие ненужных пересылок данных в сгенерированном коде), подавляющая часть современных драйверов пишется на языке ассемблера. Надёжность для драйверов играет особую роль, поскольку в Windows NT и UNIX (в том числе в Linux) драйверы работают в режиме ядра системы. Одна тонкая ошибка в драйвере может привести к краху всей системы.

Создание антивирусов и других защитных программ.

Написание трансляторов языков программирования.

Программирование арифметических выражений в языке Ассемблер происходит через некоторые команды такие, как: mul, div, sub, add. Эти команды называются командами арифметических операций.

Mul – команда умножения. Она умножает регистр axна то, что стоит после нее. Результат заносится в ax.

Div – команда деления. Она делит регистр ax на то, что стоит после нее. Результат заносится в ax.

Add – команда сложения. Слаживает два числа. Результат заносится в первый регистр.

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

Пример: Написать программу на ассемблере вычисления выражения: а – e/b – de;

обе составляющие силы сопротивления, но если мы захотим моделировать полет снаряда, выпущенного из орудия, где скорость полета почти на всем его протяжении сотни метров в секунду, то линейной составляющей силы сопротивления можно пренебречь. Проецируя уравнение на оси х и у, получаем

Поскольку в каждой точке траектории сила сопротивления направлена по касательной к траектории в сторону, противоположную движению, то

где θ - угол между текущим направлением скорости и осью х. Подставляя это в уравнение и учитывая, что , получаем уравнения движения в переменных vx, vy.

(7.12)

Поскольку представляет несомненный интерес и траектория движения, дополним систему (7.12) еще двумя уравнениями

(7.13)

и, решая их совместно с (7.12), будем получать разом четыре функции: vx(t), vy(t), x(t), y(t).

Прежде чем дать пример решения обсуждаемой задачи, покажем очень полезный прием, чрезвычайно популярный в физическом моделировании, называемый обезразмериванием. При решении конкретных задач мы пользуемся определенной системой единиц (СИ), в которой далеко не все числовые значения лежат в удобном диапазоне. Кроме того, абсолютные значения величин дают мало информации для качественного понимания. Скорость 15 м/с - много это или мало? Все дело в том, по сравнению с чем. Именно в сравнении с чем-то привычным и понятным мы обычно и воспринимаем слова «много» и «мало», даже если делаем это бессознательно. Идея обезразмеривания заключается в переходе от абсолютных значений расстояний, скоростей, времен и т.д. к относительным, причем отношения строятся к величинам, типичным для данной ситуации. В рассматриваемой задаче это особенно хорошо просматривается. В самом деле, при отсутствии сопротивления воздуха мы имеем значения l, h, t, определенные выше; сопротивление воздуха изменит характер движения, и если мы введем в качестве переменных величины

программа выдает в графическом режиме семейство траекторий, отличающихся значениями одного из трех безразмерных параметров (в данном случае b).

Программа 148. Реализация модели «Полет тела, брошенного под углом к горизонту»

Program Pod Uglom;

Uses Crt, Graph;

Type G = Array[1..4] Of Real;

Const A = 0; В =0.1; (параметры модели)

Al = Pi / 4; (угол - параметр модели}

Н = 0.001; Нрr = 0.1; (шаг интегрирования и шаг вывода результатов)

Var N, I, J, M, L, К : Integer;

Y0, Y : G; Х0, X, Xpr, A1, B1, Cosinus, Sinus : Real; LS : String;

Function Ff(I : Integer; X : Real; Y : G) : Real;

{описание правых частей дифференциальных уравнений}

Begin

Case I Of

1: Ff:=-A1*Sinus*Y[l]-Bl*Sinus*Sqrt(Sqr(Y(l])+Sqr(Y[2]))*Y[1];

2: Ff:=-Sinus-A1*Sinus*Y[1]-B1*Sinus*Sqrt(Sqr(Y(1])+Sqr(Y[2]))*Y[2];

3: Ff:=Y[1]/(2*Cosinus);

4: Ff:=2*Y[2]/Sinus

End End;

Procedure Runge_Kut (N: Integer; Var X: Real; Y0: G; Var Y: G; Н: Real);

(метод Рунге-Кутта четвертого порядка)

Var I : Integer; Z, K1, K2, КЗ, К4 : G;

Procedure Right(X : Real; Y : G; Var F : G) ;

{вычисление правых частей дифференциальных уравнений}

Var I : Integer;

Begin For I := 1 To N Do F[I] := Ff(I, X, У)

End; Begin Right(X, Y0, K1); X := X + Н / 2;

For I := 1 To N Do Z[I]:=Y0[I]+H*K1[I]/2; Right(X, Z, K2);

For I := 1 To N Do Z[I]:=YO[I]+H*K2[I]/2; Right(X, Z, КЗ); Х:=Х+Н/2;

For I := 1 To N Do Z[I] := Y0[I] + H * КЗ [I]; Right (X, Z, К4);

For I := 1 To N Do

Y[I]:=Y0[I]+H*(K1[I]+2*K2[I]+2*K3[I]+K4[I])/6;

End; {следующий блок - для получения численных результатов при одном наборе параметров}

{Begin

Sinus := Sin(Al); Cosinus := Cos(Al); Al := A; Bl := B; ClrScr;

N:=4; X0:=0; Y0[l]:=Cosinus; Y0[2]:=Sinus; Y0[3]:=0; Y0[4]:=0;

WriteLn(' время скорость координаты');

WriteLn; X := Х0; Xpr := 0; Y[4] := Y0[4];

While Y[4] >= 0 Do

Begin If X >= Xpr Then Begin

WriteLn ('t=', X : 6 : 3, ' Vx='. Y0[l] : 6 : 3, ' Vy=',

Y0[2] : 6 : 3. ' X=', y0[3] : 6 : 3, ' Y=', Y0[4] : б : 3) ;

Xpr := Xpr + Hpr

End; Runge_Kut(N, X, Y0, Y, H); Y0 := Y

End; WriteLn; WriteLn('для продолжения нажмите любую клавишу');

Repeat Until KeyPressed

Если массив был создан с помощью оператора new, то каждый его элемент получает значение по умолчанию. Каким оно будет определяется на основании типа данных (0 для int, 0.0 для double и т. д.).

Объявить имя для массива и создать сам массив можно было на одной строке по следующей схеме:

тип[] имя  = new тип[размер]; тип[] имя = {эл0, эл1, …, элN};

Примеры:

int[] mas1 = {10,20,30}; int[] mas2  = new int[3];

Чтобы обратиться к какому-то из элементов массива для того, чтобы прочитать или изменить его значение, нужно указать имя массива и за ним индекс элемента в квадратных скобках. Элемент массива с конкретным индексом ведёт себя также, как переменная. Например, чтобы вывести последний элемент массива mas1 мы должны написать в программе:

System.out.println("Последний  элемент массива " + mas1[2]);

А вот так мы можем положить в массив mas2 тот же набор значений, что хранится в mas1:

mas2[0] = 10;

mas2[1] = 20;

mas2[2] = 30;

Уже из этого примера видно, что для того, чтоб обратиться ко всем элементам массива, нам приходится повторять однотипные действия. Как вы помните для многократного повторения операций используются циклы. Соответственно, мы могли бы заполнить массив нужными элементами с помощью цикла:

for(int i=0; i<=2; i++)

{  mas2[i] = (i+1) * 10; }

Понятно, что если бы массив у нас был не из 3, а из 100 элементов, до без цикла мы бы просто не справились.

Длину любого созданного массива не обязательно запоминать, потому что имеется свойство, которое его хранит. Обратиться к этому свойству можно дописав .length к имени массива. Например:

int razmer = mas1.length;

Это свойство нельзя изменять (т. е. ему нельзя ничего присваивать), можно только читать. Используя это свойство можно писать программный код для обработки массива даже не зная его конкретного размера.

Например, так можно вывести на экран элементы любого массива с именем ar2:

for(int i = 0; i <= ar2.length  - 1; i++)

{   System.out.print(ar2[i] + "  "); }

Для краткости удобнее менять нестрогое неравенство на строгое, тогда не нужно будет вычитать единицу из размера массива. Давайте заполним массив целыми числами от 0 до 9 и выведем его на экран:

for(int i = 0; i <  ar1.length; i++)

{ar1[i] =  Math.floor(Math.random() * 10);   System.out.print(ar1[i] + "  ");}

Обратите внимание, на каждом шаге цикла мы сначала отправляли случайное значение в элемент массива с i-ым индексом, а потом этот же элемент выводили на экран. Но два процесса (наполнения и вывода) можно было проделать и в разных циклах. Например:

В программе, как уже было сказано, используется процедура FindMin, вычисляющая индекс lowindex элемента, наименьшего среди элементов массива с индексами не меньше, чемstartindex:

procedure FindMin(startindex: integer; var lowindex: integer);

var lowelem: ...;

u: integer;

begin

lowindex := startindex;

lowelem := M[startindex];

for u:=startindex+1 to N do

if M[u] < lowelem then

begin

lowelem := M[u];

lowindex := u

end

end;

между различными свойствами объектов, формулируют законы природы или общества.

База знаний — это совокупность основополагающих фактов и правил в определенной предметной области.

Рассмотренный нами пример очень простой. Здесь нетрудно догадаться о том, какие факты являются основополагающими, и сформулировать полный набор правил. В более сложных предметных областях эта задача много труднее. Часто решить ее по силам оказывается только крупному специалисту (эксперту) или коллективу специалистов, обладающих большими знаниями в данной области.

С недавних пор появилась новая специальность « инженер по знаниям», задача которого – формализация знаний, разработка баз знаний и создание на их основе систем искусственного интеллекта

Теперь познакомимся с представлением правил на Прологе. Сначала запишем правило, определяющее понятие «сын». Его можно сформулировать так:

«А является сыном для В, если В является отцом для А».

Здесь под А и В понимаются любые мужские имена. На Прологе это запишется следующим образом:

сын(А, В) :- отец(В, А).

Простейшее правило на Прологе записывается в виде двух предикатов, соединенных знаком «:-», который читается «если». Предикат, записанный слева от «:-» называется заголовком (головой) правила. Часть правила, стоящая после знака «:-», называется телом правила. Всякое правило обозначает следующее:

если имеет место тело правила, то справедлив заголовок.

В терминологии Пролога А и В называются переменными. Переменная может обозначаться одной прописной (заглавной) буквой или словом, начинающимся с прописной буквы. В данном примере А и В обозначают любое мужское имя. По смыслу переменная может быть заменена на неопределенное местоимение: кто-то, что-то, некто, нечто и т.п.

Правила обладают большей общностью, чем факты, и обычно содержат переменные. Попробуем добавить в базу знаний «Родственники» правило, определяющее, кто есть дедушка. Понятно, что Лев является дедушкой Алексею потому, что Андрей — отец Алексея, а Лев — отец Андрея. Используя понятие переменной, можно сказать иначе: «X является дедушкой для Y, если X является отцом для Z и Z является отцом для Y».

Таким образом, тело правила состоит из двух отношений, соединенных связкой «и». На Прологе это запишется так: дедушка (X,Y) :- отец (X,Z) , отец (Z,Y).

В этой записи роль связки «и» играет запятая «,».Имея определение «дедушка», сформулируем правило, определяющее, кто такой внук:

внук (X,Y) :- дедушка (Y,X).

А теперь дадим определение, кто такой брат. Имея уже достаточный опыт, мы можем сформулировать его так: X является братом для Y, если Z является отцом одновременно для X и для Y.

брат (X,Y) :- отец (Z,X), отец (Z,Y).

Рассмотрим еще один запрос к БЗ «Родственники». Нужно выяснить, кто является одновременно братом и племянником. Если цель поставить следующим образом:

? брат (X,Y), племянник (X,Z),

то в результате получим:

Х = Михаил, Y= Дмитрий, Z = Андрей;

Х = Дмитрий, Y = Михаил, Z = Андрей.

На запросы второго типа Пролог выдает все значения переменных, упомянутых в формулировке цели. В данном случае искомым ответом является значение переменной X. Информация о брате (Y) и дяде (Z) — избыточна. Но если запрос построить в такой форме:

? брат (Х,_), племянник (Х,_),

то ответом будет:

Х = Михаил; Х = Дмитрий.

Здесь дважды использован «пустой» аргумент, отмечаемый символом подчеркивания «_». Пустой аргумент обозначает любое значение. Запрос можно переформулировать так: найти X, который является братом кому угодно и племянником кому угодно. Поскольку в формулировке цели присутствует только одна переменная (X), то ее значение и выводится.

Рассмотрим еще один пример с информацией о родственных отношениях, представленных следующим графом:

Очевидно, в базу знаний войдут два факта:

отец («Андрей», «Алексей»);

мать («Ольга», «Алексей»).

А теперь определим отношение «сын» в форме правила. Человек является сыном как матери, так и отцу. Поэтому формально можно сказать так: «X является сыном для Y, если Y является отцом для X или Y является матерью для X».

Здесь возникает логическая связка «или», которой нет в стандарте Пролога (в Турбо-Прологе она есть). Тем не менее из положения можно выйти, дважды сформулировав правило, определяющее отношение сын:

сын(Х,Y ):-отец(Y,Х); сын(Х,Y):-мать(Y,Х).

Теперь на вопрос к этой базе знаний ?сын(Х, «Ольга») получим ответ: Х=Алексей. А на вопрос ?сын(Х, «Андрей» ) ответ будет Х=Алексей. На вопрос

?сын(Х,Y)

получим ответ

Х=Алексей, Y=Андрей; Х=Алексей, Y=Ольга.

Алгоритм, по которому система Пролог ищет в базе знаний ответы на поставленные вопросы, называется механизмом вывода Пролога.

удал (X. [Z I Y], [Z I W]) : - удал (X, Y, W) .

Декларативный смысл: если удаляемый элемент совпадает с головой списка, то результатом программы является хвост списка, иначе удаления производятся из хвоста списка.

Данная программа удаляет первое вхождение в список элемента, связанного с переменной X. Знак отсечения "!"в конце правила предотвращает последующий поиск и вывод лишних вариантов ответов после выполнения ограничительного факта.

Для удаления всех вхождений элемента Х программу надо дополнить:

удал (Х,[ ],[]).

удал (X, [X | Y], W) :- удал (X, Y, W).

удал (X, [Z I Y], W):- удал (X, Y, W).

Декларативный смысл программы таков: пока список не пуст, удалить элемент, если он совпадает с головой списка, значит, отбросить голову списка, а затем удалять его из оставшегося хвоста, иначе надо сразу удалять элемент из хвоста.

Пример 5: индексация элементов списка.

Смысл программы 127 состоит в том, чтобы получить элемент под номером N или узнать номер элемента X.

получить ([X | Y], 1, X).

получить ([W | Y], N, X) :- N is M+l, получить (Y, M, X).

Пример 6: поиск максимального элемента.

max ([X], X).

max ([X | Y], X) :- шах (Y, W), X>W, !.

max ([X | Y], W) :-max (Y, W).

Декларативный смысл программы: если в списке один элемент - он и является максимальным, если более одного, то это голова списка, если она больше максимального элемента хвоста, или максимальный элемент хвоста.

Пример 7: обращение списка.

Данная задача - самая сложная из рассмотренных. Для ее решения важно сообразить, что обратить список из одного элемента - означает оставить список без изменения. Обратить более длинный список - обратить его хвост, а потом сзади приставить к нему голову исходного списка.

обр ([X], [X]) .

обр ([X I Y], Z) :- обр (Y, W), присоединить (W, [X], Z).

В этой программе используется процедура слияния списков, описанная выше.

Arity-Prolog располагает значительным числом встроенных предикатов для обработки списков, так что приведенные программы имеют, в основном, учебный характер.

как если бы он был полем записи:

var

FirstPozition : Pozition;

FirstPozition.Init(10,15);

Метод задается так же, как и процедура в модуле: внутри объекта записывается заголовок (как в секции Interface модуля); при этом все поля, используемые мето-дом, должны предшествовать его объявлению. Определение метода (расшифровка действий) происходит вне объявления объекта. Имя метода должно предваряться названием типа объекта, которому метод принадлежит, сопровождаемым точкой. Например,

procedure Pozition. Init(CoordX, CoordY: integer);

begin

X: = CoordX: Y: = CoordY; end;

Заметим, что имена формальных параметров метода не могут совпадать с именами полей данных объекта.

Также как модуль скрывает детали реализации процедур от пользователя, объект может скрывать свои поля и методы. Для этого используется ключевое слово private (личный). Личные поля и методы доступны только внутри метода. Объявление выглядит следующим образом:

type

ObjectName=object

поле; … поле; метод; метод; private поле; … поле; метод; … метод; end;

Наследование. Рассмотрим точку с координатами Х и Y. Ее можно сделать видимой или невидимой, ей можно задать цвет, ее можно переместить. Создадим объект с такими возможностями:

Point=object

X,Y : integer; "

procedure Init(CoordX, CoordY : integer);

function GetX : integer;

function GetY . integer;

Visible: Boolean;

Color: Word;

procedure Init(CoordX, CoordY : integer; InitCoIor : Word);

function Is Visible : Boolean;

procedure Show;{показывает точку}

procedure Blind; {стирает точку}

procedure Jump(NextX, NextY : integer);{nepeMeiuaer точку} end;

Заметим, однако, что поля X.Y и методы GetX, GetY практически совпадают с соответствующими полями и методами объекта Pozition.

Турбо-Паскаль предоставляет возможность учесть эту ситуацию. Следует считать тип объекта Point порожденным типом Pozition, записав это следующим образом:

Point=object(Pozition)

Visible : Boolean; Color : Word;

procedure Init(CoordX, CoordY : integer; InitColor : Word);

function Is Visible . Boolean;

procedure Show; procedure Blind:

procedure Jump(NextX, NextY : integer); end;

Объект Point теперь наследует свойства объекта Pozition. Поля X,Y явно не заданы в Point, но Point ими обладает благодаря наследованию, т.е. можно написать Point.X:=17;

← Предыдущая
Страница 1
Следующая →

Файл

остальные шпоры.docx

остальные шпоры.docx
Размер: 591 Кб

.

Пожаловаться на материал

В информатике совокупность взаимосвязанных данных называется информационной структурой. Компьютерные сети. Языки программирования. Язык разметки HTML. ЭВМ. Информационная система

У нас самая большая информационная база в рунете, поэтому Вы всегда можете найти походите запросы

Искать ещё по теме...

Эта тема принадлежит разделу:

Информатика. Шпоры

В информатике совокупность взаимосвязанных данных называется информационной структурой. Компьютерные сети. Языки программирования. Язык разметки HTML. ЭВМ. Информационная система

К данному материалу относятся разделы:

Табличные процессоры

Реляционные БД. Правила Кодда. Аномалии. Нормальные формы

Правил Кодда

Компьютерные сети

Базы данных. Классификация. Архитектура

Парадигмы программирования. Языки программирования. Системы программирования

Язык разметки HTML. Web-страницы. Создание

История развития ВТ

Поколения ЭВМ

Программное обеспечение ЭВМ

Информационная система (ИС)

SQL. Команды определения данных

Язык программирования Delphi

Основные принципы функционирования ЭВМ. Основные структурные элементы современного компьютера. Функции и характеристики

Динамическое программирование

SQL. Команды управления данными

Методы сортировки и поиска. Алгоритмы и программы

Симплекс-метод

Язык JAVA-Script

Исследование операций

Кодирование информации

Компьютерное моделирование в экологии

Машинно-ориентированные языки программирования. Арифметические команды и команды условного перехода в ассемблере

Компьютерное моделирование физических процессов

Массивы в ООП-языках. Примеры использования

Рекурсивно-логическое программирование. Пролог. Основные принципы работы с базами знаний

Работа со списками в Прологе

Основные концепции ООП

Похожие материалы:

Юриспруденция. Методические указания

Методические указания по выполнению и защите выпускной квалификационной работы для направления подготовки 030900 – Юриспруденция

Задачи с решением

Технологія вивчення освітніх галузей у початковій школі

Тестові завдання з курсу "Технологія вивчення освітніх галузей у початковій школі"

Организация кассовых операций и их документирование

Дипломная работа

Экономикалық бөлім

 Электронды сәулелік балқытып біріктіру көмегімен қатты буазды гироскопты дайындау технологиясының өңделуінен бастап, орындалуына дейін нәтижені бағалау