Бьерн Страуструп - Язык программирования С++. Вступление, глава 1 - Объектно-ориентированное программирование
ОГЛАВЛЕНИЕ
1.2.5 Объектно-ориентированное программирование
Проблема состоит в том, что мы не различаем общие свойства фигур (например, фигура имеет цвет, ее можно нарисовать и т. д.) и свойства конкретной фигуры (например, окружность - это такая фигура, которая имеет радиус, она изображается с помощью функции, рисующей дуги и т. д.). Суть объектно-ориентированного программирования в том, что оно позволяет выражать эти различия и использует их. Язык, который имеет конструкции для выражения и использования подобных различий, поддерживает объектно-ориентированное программирование. Все другие языки не поддерживают его. Здесь основную роль играет механизм наследования, заимствованный из языка Симула. Вначале определим класс, задающий общие свойства всех фигур:
class shape
{
point center;
color col;
// ...
public:
point where () { return center; }
void move ( point to ) { center = to; draw(); }
virtual void draw ();
virtual void rotate ( int );
// ... };
Те функции, для которых можно определить заявленный интерфейс, но реализация которых (т. е. тело с операторной частью) возможна только для конкретных фигур, отмечены служебным словом virtual (виртуальные). В Симуле и С++ виртуальность функции означает: "функция может быть определена позднее в классе, производном от данного". С учетом такого определения класса можно написать общие функции, работающие с фигурами:
void rotate_all ( shape v [], int size, int angle )
// повернуть все элементы массива "v" размера "size"
// на угол равный "angle"
{
int i = 0;
while ( i<size )
{
v [ i ] . rotate ( angle );
i = i + 1;
}
}
Для определения конкретной фигуры следует указать, прежде всего, что это - именно фигура и задать ее особые свойства (включая и виртуальные функции):
class circle : public shape
{
int radius;
public:
void draw () { /* ... */ };
void rotate ( int ) {} // да, пока пустая функция
};
В языке С++ класс circle называется производным по отношению к классу shape, а класс shape называется базовым для класса circle. Возможна другая терминология, использующая названия "подкласс" и "суперкласс" для классов circle и shape соответственно. Теперь парадигма программирования формулируется так:
Определите, какой класс вам необходим; предоставьте полный набор операций для каждого класса; общность классов выразите явно с помощью наследования.
Если общность между классами отсутствует, вполне достаточно абстракции данных. Насколько применимо объектно-ориентированное программирование для данной области приложения определяется степенью общности между разными типами, которая позволяет использовать наследование и виртуальные функции. В некоторых областях, таких, например, как интерактивная графика, есть широкий простор для объектно-ориентированного программирования. В других областях, в которых используются традиционные арифметические типы и вычисления над ними, трудно найти применение для более развитых стилей программирования, чем абстракция данных. Здесь средства, поддерживающие объектно-ориентированное программирование, очевидно, избыточны.
Нахождение общности среди отдельных типов системы представляет собой нетривиальный процесс. Степень такой общности зависит от способа проектирования системы. В процессе проектирования выявление общности классов должно быть постоянной целью. Она достигается двумя способами: либо проектированием специальных классов, используемых как "кирпичи" при построении других, либо поиском похожих классов для выделения их общей части в один базовый класс.
С попытками объяснить, что такое объектно-ориентированное программирование, не используя конкретных конструкций языков программирования, можно познакомиться в работах [2] и [6], приведенных в списке литературы в главе 11.
Итак, мы указали, какую минимальную поддержку должен обеспечивать язык программирования для процедурного программирования, для упрятывания данных, абстракции данных и объектно-ориентированного программирования. Теперь несколько подробнее опишем средства языка, хотя и не самые существенные, но позволяющие более эффективно реализовать абстракцию данных и объектно-ориентированное программирование.