
Лекция 1
Основные парадигмы программирования
По мере роста объема обрабатываемой информации и усложнения решаемых задач возникали различные модели или идеи программирования. Некоторые идеи становились общепринятыми и образовывали на некоторое время так называемую парадигму программирования.
Первой парадигмой было процедурное программирование. Суть этой идеи заключается в следующем. Программист оформляет свою программу в виду нескольких наиболее простых процедур и функций. Написать и отладить небольшую процедуру можно легко и быстро. Остается только собрать все процедуры в нужном порядке. Типичным примером процедурно-ориентированного языка является Fortran.. Используя процедурную модель, программист мог писать программы длиной до нескольких тысяч строк.
По мере прогресса в области вычислительной математики акцент в программировании стал смещаться с процедур в сторону организации данных. Возникла идея структурного программирования, основанная на использовании различных структур данных. Появились структурированные языки Algol 60, Pascal, Ada, Modula-2 и C. Использую структурное программирование, программист мог создавать и сопровождать программы объемом до нескольких десятков тысяч строк. Структурное программирование стало парадигмой.
Усложнение задач привело к тому, что программы стали содержать огромное количество процедур и функций. Возникла идея объединить данные и процедуры их обработки в один модуль. Это позволило упростить структуру программ, то есть представить ее в виде меньшего количества более крупных блоков и минимизировать связи между ними. Идея модульного программирования стала парадигмой. Модуль представлял собой набор данных и процедур, которые механически объединялись в единое целое. Программы составлялись из отдельных модулей. Эффективность модульных программ тем выше, чем меньше модули зависят друг от друга. Для того чтобы обеспечить максимальную независимость модулей, надо четко определить процедуры, которые будут вызываться другими модулями, от вспомогательных, которые обрабатывают данные, включенные в этот модуль.
По мере усложнения решаемых задач размеры программ достигали сотни тысяч строк. Структурное и модульное программирование не могли поддерживать такие проекты.
Появилась идея классов. Класс – это объединение данных и процедур их обработки. Идея классов стала основой объектно-ориентированного программирования(ООП). Фактически ООП можно рассматривать как модульное программирование модульного уровня, когда вместо механического, во многом случайного, объединения процедур и данных акцент делается на их смысловую связь. Основные принципы ООП были разработаны в языке Симула -67, а затем развиты в языках С++ и Java. ООП стало парадигмой программирования. Следует отметить, что преимущества ООП в полной мере проявляются лишь при разработке достаточно сложных программ. Бессмысленно прибегать к этим средствам при создании простейших программ. ООП широко применяется при разработке графических интерфейсов приложений, при создании сетевых приложений, приложений баз данных и в компьютерной графике.
Основные принципы ООП
Основными принципами ООП являются инкапсуляция, наследование и полиморфизм.
Инкапсуляция- это механизм, который связывает данные с процедурами их обработки, и сохраняет их в безопасности, как от внешнего влияния, так и ошибочного использования.
Наследование– это процесс построения иерархии классов, когда потомки наследуют все свойства своих предков, могут их изменять и добавлять новые. Классы-предки называются базовыми, а классы-потомки – производными. Иерархия классов представляется в виде древовидной структуры. В С++ каждый класс может иметь сколько угодно предков и потомков.
Полиморфизм– это свойство, позволяющее одинаково называть сходные по смыслу процедуры родственных классов , но реализовывать их действия по-разному.
Следует отметить, что проектирование объектно-ориентированной программы представляет собой очень сложную задачу. Вначале решается вопрос о применимости ООП к решению задачи. Для этого необходимо оценить степень общности между классами. На следующем этапе проектирования разрабатываются классы и изучаются возможности выделения в классах тех свойств, которые могут быть переданы базовому классу. Затем, проектируются те интерфейсы, которыми будут обмениваться объекты, и осуществляется реализация разработанных объектов и интерфейсов.
Описание класса
Класс является абстрактными типом данных, определяемым пользователем, и представляет собой объединение данных и функций для работы с ними.
Данные класса называются полями (или компонентными данными или данными-членами), а функции класса – методами (или компонентными функциями, или функциями-членами). Поля и методы будем называть элементами классов.
Синтаксис описания простого класса:
class <имя класса>
{
[private:]
<описание скрытых элементов>
public:
<описание доступных элементов>
};
Здесь <имя класса>-идентификатор. Спецификаторы доступа private и public управляют видимостью элементов класса. Элементы, описанные после слова private ,видимы только внутри класса. По умолчанию все элементы класса являются закрытыми. Это означает,
что к ним невозможно обратиться из функций, не являющихся членами класса. Таким образом достигается инкапсуляция- доступ к закрытым элементам классов строго контролируется.
Для того, чтобы открыть элементы класса, т.е. сделать их доступными для любых функций программы, можно объявить их с помощью ключевого слова public.
Рекомендуется все поля объявлять закрытыми, а методы для доступа к ним- открытыми.
Действие любого спецификатора распространяется до следующего спецификатора или до конца класса.
Поля класса могут иметь любой тип, кроме типа этого же класса, но могут быть указателями или ссылками на этот класс.
Инициализация полей в описании класса не допускается, так как класс – это абстрактный тип, не связанный с памятью компьютера.
Внутри определения класса методы идентифицируются своими прототипами
Пример: Создать класс «комплексное число». Включим в этот класс 2 поля для действительной и мнимой частей, функцию, определяющую комплексное число, и функцию, осуществляющую вывод значения комплексного числа на экран.
class complex1
{ double real;
double image;
public:
void define(double re=0.0,double im=0.0);
void display();
};
При определении метода класса необходимо сообщить компьютеру, какому классу он принадлежит с помощью операции доступа к области видимости ‘::’.
Методы define() и display() можно определить, например, так:
void complex1::define(double re. double im)
{real=re;
image=im;
}
void complex1::display()
{cout<<”\n”<<”real=”<<real;
cout<<”\n”<<”image=”<<image;
}
Замечания
1.Описания данных одного типа в определении класса могут быть объединены, например:
class complex1
{ double real.image;
public:
…
};
2.Для обращения к элементу класса из тела метода достаточно указать только имя элемента. Например, в теле функции display() мы ссылаемся на элемент real класса complex1,указывая только его имя.
3. В описание класса можно включать полное определение метода, если его тело является коротким. Например:
class complex1
{double real,image;
public:
void define(double re, double im)
{real=re;
image=im;
}
void display()
{ cout<<”\n”<<”real=”<<real;
cout<<”\n”<<”image=”<<image;
}
};