Оспаривание эффективности разработки методами ООП.
Критики оспаривают тезис о том, что разработка объектно-ориентированных программ требует меньше ресурсов или приводит к созданию более качественного ПО. Проводится сравнение затрат на разработку разными методами, на основании которого делается вывод об отсутствии у ООП преимуществ в данном направлении. Учитывая крайнюю сложность объективного сравнения различных разработок, подобные сопоставления, как минимум, спорны.
Производительность объектно-ориентированных программ.
Указывается на то, что целый ряд «врождённых особенностей» ООП-технологии делает построенные на её основе программы технически менее эффективными, по сравнению с аналогичными необъектными программами. Не отрицая действительно имеющихся дополнительных накладных расходов на организацию работы ООП-программ (см. раздел «Производительность» выше), нужно, однако, отметить, что значение снижения производительности часто преувеличивается критиками. В современных условиях, когда технические возможности компьютеров чрезвычайно велики и постоянно растут, для большинства прикладных программ техническая эффективность оказывается менее существенна, чем функциональность, скорость разработки и сопровождаемость. Лишь для некоторого, очень ограниченного класса программ (ПО встроенных систем, драйверы устройств, низкоуровневая часть системного ПО, научное ПО) производительность остаётся критическим фактором.
|
|
Критика отдельных технологических решений в ООП-языках и библиотеках.
Эта критика многочисленна, но затрагивает она не ООП как таковое, а приемлемость и применимость в конкретных случаях тех или иных реализаций её механизмов. Одним из излюбленных объектов критики является язык 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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!