Оспаривание эффективности разработки методами ООП.



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

Производительность объектно-ориентированных программ.

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

Критика отдельных технологических решений в ООП-языках и библиотеках.

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

Объектно-ориентированные языки

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

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

· Объявление классов с полями (данными - членами класса) и методами (функциями - членами класса).

· Механизм расширения класса (наследования) - порождение нового класса от существующего с автоматическим включением всех особенностей реализации класса-предка в состав класса-потомка. Большинство ООП-языков поддерживают только единичное наследование.

· Средства защиты внутренней структуры классов от несанкционированного использования извне. Обычно это модификаторы доступа к полям и методам, типа public, private, обычно также protected, иногда некоторые другие.

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

· Полиморфное поведение экземпляров классов за счёт использования виртуальных методов. В некоторых ООП-языках все методы классов являются виртуальными.

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

· Конструкторы, деструкторы, финализаторы.

· Свойства (аксессоры).

· Индексаторы.

· Интерфейсы - как альтернатива множественному наследованию.

· Переопределение операторов для классов.

Часть языков (иногда называемых «чисто объектными») целиком построена вокруг объектных средств - в них любые данные (возможно, за небольшим числом исключений в виде встроенных скалярных типов данных) являются объектами, любой код - методом какого-либо класса, и невозможно написать программу, в которой не использовались бы объекты. Примеры подобных языков - C#, Smalltalk, Java, Ruby. Другие языки (иногда используется термин «гибридные») включают ООП-подсистему в исходно процедурный язык. В них существует возможность программировать, не обращаясь к объектным средствам. Классические примеры - C++ и Pascal.

 

Общие сведения о классах

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

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

Объектно-ориентированное программирование (ООП) - представляет собой технологию разработки программ с использованием объектов.

Класс имеет имя, состоит из полей, называемых членами класса и функций - методов класса.

Рассмотрим пример определения класса complex.

class complex {

public:

float x;

float y;

float modul( ) {return pow(x*x+y*y,0.5);}

float argument() {return pow(x*x+y*y,0.5);}

void show_complex()

}

и пример его использования

Листинг 1.

#include <iostream.h>

#include <math.h>

#define PI 3.14159

class complex {

public:

float x;

float y;

float modul() {return pow(x*x+y*y,0.5);}

float argument() {return atan2(y,x)*180/PI;}

void show_complex() {if (y>=0) cout<<x<<"+"<<y<<"i"<<endl;

else cout<<x<<y<<"i"<<endl;}

};

int main()

 

{

// Объявление переменной класса chislo

complex chislo; chislo.x=3.5; chislo.y=-1.432;

chislo.show_complex();

cout<<"Модуль числа"<<chislo.modul();

cout<<endl<<"Аргумент числа"<<chislo.argument()<<endl;

return EXIT_SUCCESS;

}

Если поля структуры доступны всегда, то при использовании классов могут быть члены, доступные (публичные) (описатель public), с помощью оператора . ("точка") и приватные (описатель private), доступ к которым возможен только с помощью публичных методов. Методы также могут быть публичными и приватными. Вызов приватных методов осуществляется из публичных.

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

Рассмотрим пример работы с классом complex, в котором члены являются приватными.

Листинг 2.
#include "stdafx.h"
#include <iostream.h>
#include <math.h>
#define PI 3.14159
class complex {
//Публичные методы
public:
void znach();
float modul();
float argument();
//Приватные члены и методы
private:
float x;
float y;
void show_complex();
};
void complex::znach()
{
cout<<"VVedite x\t";
cin>>x;
cout<<"Vvedite y\t";
cin>>y;
// Вызов приватного метода
show_complex();
}
float complex::modul()
{
return pow(x*x+y*y,0.5);
}
float complex::argument()
{
return atan2(y,x)*180/PI;
}
void complex::show_complex()
{
if (y>=0) cout<<x<<"+"<<y<<"i"<<endl;
else cout<<x<<y<<"i"<<endl;
}
int main(int argc, char *argv[])
{
complex chislo;
chislo.znach();
cout<<"Modul kompleksnogo chisla="<<chislo.modul();
cout<<endl<<"Argument kompleksnogo chisla="<<chislo.argument()<<endl;
return 1;
}

Результат работы программы

VVedite x 3
Vvedite y -1
3-1i
Modul kompleksnogo chisla=3.16228
Argument kompleksnogo chisla=-18.435
Press any key to continue

Функция-конструктор

Как видно, из рассмотренных примеров в большинстве при создании объекта экземпляра-класса необходимо присвоить начальные значения некоторым членам класса. В предыдущем примере для этого использовался метод chislo.znach(), однако для упрощения процесса инициализации объекта предусмотрена специальная функция, которая называется конструктором. Имя конструктора совпадает с именем класса, конструктор запускается автоматически при создании экземпляра класса. Функции-конструкторы не возвращают значение, но при описании функции конструктора не следует указывать в качестве возвращаемого значения тип void.

На листинге 3 приведен класс complex с использованием конструктора.

Листинг 3.
#include "stdafx.h"
#include <iostream.h>
#include <math.h>
#define PI 3.14159
class complex {
public:
complex();
float modul();
float argument();
private:
float x;
float y;
void show_complex();
};
int main(int argc, char *argv[])
{
complex chislo;
cout<<"Modul kompleksnogo chisla="<<chislo.modul();
cout<<endl<<"Argument kompleksnogo chisla="<<chislo.argument()<<endl;
return 1;
}
complex::complex()
{
cout<<"VVedite x\t";
cin>>x;
cout<<"Vvedite y\t";
cin>>y;
show_complex();
}
float complex::modul()
{
return pow(x*x+y*y,0.5);
}
float complex::argument()
{
return atan2(y,x)*180/PI;
}
void complex::show_complex()
{
if (y>=0) cout<<x<<"+"<<y<<"i"<<endl;
else cout<<x<<y<<"i"<<endl;
}

Если члены класса, являются массивами (указателями), то конструктор может взять на выделение памяти для него. Рассмотрим пример.

ЗАДАЧА. Заданы координаты n точек в к-мерном пространстве. Найти точки, расстояние между которыми наибольшее и наименьшее.
Листинг 4.
#include "stdafx.h"
#include <iostream.h>
#include <math.h>
class prostr{
public:
prostr();
float poisk_min();
float poisk_max();
int vivod_result();
int delete_a();
private:
int n;
int k;
float **a;
float min;
float max;
int imin;
int jmin;
int imax;
int jmax;
};
void main()
{
prostr x;
x.poisk_max();
x.poisk_min();
x.vivod_result();
x.delete_a();
}
prostr::prostr()
{
int i,j;
cout<<"VVedite razmernost prostrantva ";
cin>>k;
cout<<"VVedite kolichestvo tochek ";
cin>>n;
a=new float*[k];
for(i=0;i<k;i++)
a[i]=new float[n];
for(j=0;j<n;j++)
{
cout<<"VVedite koordinati "<<j<<" tochki"<<endl;
for(i=0;i<k;i++)
cin>>a[i][j];
}

}
float prostr::poisk_max()
{
int i,j,l;
float s;
for(max=0,l=0;l<k;l++)
max+=(a[l][0]-a[l][1])*(a[l][0]-a[l][1]);
max=pow(max,0.5);
imax=0;jmax=1;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
for(s=0,l=0;l<k;l++)
s+=(a[l][i]-a[l][j])*(a[l][i]-a[l][j]);
s=pow(s,0.5);
if (s>max)
{
max=s;
imax=i;
jmax=j;
}
}
return 0;
}
float prostr::poisk_min()
{
int i,j,l;
float s;
for(min=0,l=0;l<k;l++)
min+=(a[l][0]-a[l][1])*(a[l][0]-a[l][1]);
min=pow(min,0.5);
imin=0;jmin=1;
for(i=0;i<k;i++)
for(j=i+1;j<n;j++)
{
for(s=0,l=0;l<k;l++)
s+=(a[l][i]-a[l][j])*(a[l][i]-a[l][j]);
s=pow(s,0.5);
if (s<min)
{
min=s;
imin=i;
jmin=j;
}
}
return 0;
}
int prostr::vivod_result()
{
int i,j;
for(i=0;i<k;cout<<endl,i++)
for (j=0;j<n;j++)
cout<<a[i][j]<<"\t";
cout<<"max="<<max<<"\t nomera "<<imax<<"\t"<<jmax<<endl;
cout<<"min="<<min<<"\t nomera "<<imin<<"\t"<<jmin<<endl;
return 0;
}
int prostr::delete_a()
{
delete [] a;
return 0;
}


Дата добавления: 2019-09-13; просмотров: 197; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!