Небольшие учебные программы, которые написаны специально для этой статьи, помогут начинающим увидеть разницу между ООП и обычным процедурным программированием. В материале мы коснемся конкретных языков — С и Java.
Вычисление площади
Вычисление площадей двумерных геометрических фигур, наверное, одно из самых несложных заданий для начинающих программистов. Споткнуться здесь не обо что — все формулы на виду, в интернете и совсем необязательно лезть в ряды Фурье или интегралы. Достаточно обычных знаний из школьного курса алгебры.
Известно, что площадь квадрата равна квадрату длины его стороны, площадь прямоугольника равна произведению длин двух его смежных сторон, площадь круга равна произведению квадрата радиуса на число Пи, а для вычисления площади треугольника используем формулу Герона с полупериметром.
Просто подставим переменные будущих программ в наши методы или функции, а результат вернём командой return.
p = 0.5*(x+y+z);
//Функция вычисления площади треугольника
float areatriangle(float p, float x, float y, float z)
{
return (sqrt(p*(p-x)*(p-y)*(p-z)));
}
Естественно, в начале пользователь должен будет ввести значения переменных в программу. Для этого используем в С — оператор scanf, в Java — объект класса BufferedReader, который заносит вводимые символы в буфер и позволяет дальше работать с ними.
ООП и не-ООП
А вот дальше начинаются серьёзные различия. Если в языке С достаточно несложно работать с функциями, их просто нужно объявить заранее, до основной функции main (так делать удобнее, потому как не нужно следить за тем, чтобы объявление функции не шло раньше, чем её вызов). А описать функции можно после завершения main.
//Объявляем функции
float areasquare(float x);
//Функция вычисления площади прямоугольника
float arearestangle(float x, float y)
{
return x*y;
}
В языке Java вам уже придется создавать методы, а это уже более широкая и сложная абстракция, чем функции, поскольку методы могут находиться, вообще, в другом классе или даже пакете. Мы, кстати, так и сделали — разместили наши методы (то есть, по сути, формулы из переменных с возвращаемым результатом) в другом классе и оттуда будем их вызывать. Причём, вызовем их сразу в функцию printf (она есть и в С и в Java), чтобы сразу напечатать значения, а не расписывать вывод отдельно.
//Печать результата «на ходу», через вызов функции printf
System.out.printf ("rezalt %f\n", ar.area(x, y));
}
В обеих программах мы создадим некое подобие проверки на корректность ввода данных. Скорее, это даже не проверка, а только намек, поскольку проверять мы будем лишь значение счетчика, которое предлагается выбрать пользователю. У нас четыре фигуры, пользователь должен выбрать одну из цифр: от единицы до четверки, иначе программа не будет иметь смысла.
if ((l > 4)||(l < 1)||((int)(isalpha(l))==1)) {
printf ("Vi namerenno pitaetes zaputat programmu ");
getch();
}
К слову, реализация выбора могла быть сделана и по-другому — допустим, через оператор switch. Но мы выбрали условия и циклы, так как это более наглядно.
Все наши данные, в том числе и строковые, занесены в переменные, чтобы ими было удобно оперировать. К примеру, если вы захотите добавить в нашу программу ещё 20 методов или, в случае с C — функций, то вам проще будет оформить пользовательский ввод (объяснить юзеру, что ему водить) с помощью переменных, а не переписывать или копировать весь текст.
char c1[] = "kvadrata";
char c2[] = "kruga";
char c3[] = "pryamougolnika";
char c4[] = "treugolnika";
char c5[] = "Esli vy hotite vichislit plochad";
Переопределение
Если внимательно посмотреть на файл area_metods программы Java, то можно увидеть, что название метода у нас всего одно — area. То есть, если в языке С мы расписывали каждую функцию отдельно, то здесь нам это не нужно. Методы с разным числом параметров компилятор Java будет считать разными. Это называется переопределением. То есть, компилятор сам вызовет нужный метод, в соответствии с тем, сколько и каких параметров будет введено пользователем. Один — сработает метод вычисления площади квадрата, два — прямоугольника и т.д.
Ради красивого переопределения пришлось пойти даже на некоторые жертвы. В частности, в методе вычисления площади круга, где необходим квадрат радиуса, мы указали две переменные, r и r1, в которых будет указано одно и то же число, введенное пользователем — радиус.
//Функция вычисления площади круга
double area(double pi, double r, double r1)
{
return (pi*(r*r1));
}
Получится удобный метод с тремя параметрами, сигнатура которого будет отличаться от остальных. А переменные мы потом присвоим в вызывающем классе: Double r = r1.
Итоги
Стоит отметить тот факт, что язык С гораздо проще современных языков с поддержкой ООП, хотя и является их основой (они почти полностью копируют его синтаксис — в этом можно убедиться по нашим программам). Java, С# и т.д., даже в упрощенном виде гораздо сложнее С, в том числе и для понимания. Этим приходится платить за поддержку современных технологий и удобную работу с большими проектами, насыщенными огромным объемом разнородных данных.
Листинг программы на С:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <math.h>
//Объявляем функции
float areasquare(float x);
float arearestangle(float x, float y);
float areasircle(float pi, float r);
float areatriangle(float p, float x, float y, float z);
int main () {
//Наши переменные - радиус, длины сторон, периметр, число pi
float r = 0;
float x = 0;
float y = 0;
float z = 0;
float p = 0;
float pi = M_PI;
//Служебная переменная - маркер попыток
int l = 0;
//Служебные переменные с текстом
char c1[] = "kvadrata";
char c2[] = "pryamougolnika";
char c3[] = "kruga";
char c4[] = "treugolnika";
char c5[] = "Esli vy hotite vichislit plochad";
char ch[] = "Vvedite";
printf (" %s %s, vvedite 1\n\n", c5, c1);
printf ("%s %s, %s 2\n\n", c5, c2, ch);
printf("%s %s, %s 3\n\n", c5, c3, ch);
printf ("%s %s, %s 4\n\n", c5, c4, ch);
scanf ("%d", &l);
if ((l > 4)||(l < 1)||((int)(isalpha(l))==1)) {
printf ("Vi namerenno pitaetes zaputat programmu ");
getch();
}
//Условия с выводом функций
if (l == 1){
printf ("Vvedite dlinu storony kvadrata\n\n");
//Ввод данных
scanf ("%f\n", &x);
//Печать результата с вызовом функции
printf ("rezalt %f\n", areasquare(x));
getch();
}
if (l == 2){
printf ("Vvedite dlinu dvux smejnix storon pryamougolnika\n\n");
//Ввод данных
scanf ("%f", &x);
scanf ("%f", &y);
//Печать результата с вызовом функции
printf ("rezalt %2f\n", arearestangle(x, y));
getch();
}
if (l == 3){
printf ("Vvedite dlinu radiusa kruga\n\n");
//Ввод данных
scanf ("%f", &r);
//Печать результата с вызовом функции
printf ("rezalt %2f\n", areasircle(pi, r));
getch();
}
if (l == 4){
printf ("Vvedite dlinu trex storon treugolnika\n\n");
//Ввод данных
scanf ("%f%f%f", &x,&y,&z);
p = 0.5*(x+y+z);
//Печать результата с вызовом функции
printf ("rezalt %2f\n", areatriangle(p, x, y, z));
getch();
}
return 0;
}
//После окончания функции main расписываем тела всех функций
//Функция вычисления площади квадрата
float areasquare(float x)
{
return (pow(x, 2));
}
//Функция вычисления площади прямоугольника
float arearestangle(float x, float y)
{
return x*y;
}
//Функция вычисления площади круга
float areasircle(float pi, float r)
{
return (pi*(pow(r));
}
//Функция вычисления площади треугольника
float areatriangle(float p, float x, float y, float z)
{
return (sqrt(p*(p-x)*(p-y)*(p-z)));
}
Листинг программы на Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
//Основной класс ( где расположен метод main)
public class area {
public static void main(String[] args) throws NumberFormatException, IOException {
// TODO Auto-generated method stub
area_metods ar = new area_metods();
//Наши переменные - радиус, длины сторон, периметр, число pi
double r = 0;
double x = 0;
double y = 0;
double z = 0;
double p = 0;
double pi = Math.PI ;
//Служебные переменные с текстом
String c1 = "kvadrata";
String c2 = "pryamougolnika";
String c3 = "kruga";
String c4 = "treugolnika";
String c5 = "Esli vy hotite vichislit plochad";
String ch = "Vvedite";
//Служебная переменная - маркер попыток
int l = 0;
System.out.printf (" %s %s, vvedite 1\n\n", c5, c1);
System.out.printf ("%s %s, %s 2\n\n", c5, c2, ch);
System.out.printf("%s %s, %s 3\n\n", c5, c3, ch);
System.out.printf("%s %s, %s 4\n\n", c5, c4, ch);
BufferedReader br = new BufferedReader
(new InputStreamReader (System.in));
//Обработка ошибок
try {
l = Integer.parseInt(br.readLine());
}
catch (NumberFormatException e) {
System.out.println ("Vi namerenno pitaetes zaputat programmu ");
System.exit(0);
}
//Проверка на соответствие условию ввода
if ((l > 4)||(l < 1)) {
System.out.println ("Vi namerenno pitaetes zaputat programmu ");
System.exit(0);
}
//Условия с выводом функций
if (l == 1){
//Ввод данных
BufferedReader br1 = new BufferedReader
(new InputStreamReader (System.in));
System.out.println ("Vvedite dlinu storony kvadrata\n\n");
x = Double.parseDouble(br1.readLine());
//Печать результата с вызовом функции
System.out.printf ("rezalt %f\n", ar.area(x));
}
if (l == 2){
//Ввод данных
BufferedReader br2 = new BufferedReader
(new InputStreamReader (System.in));
System.out.println ("Vvedite dlinu dvux smejnix storon pryamougolnika\n\n");
x = Double.parseDouble(br2.readLine());
BufferedReader br3 = new BufferedReader
(new InputStreamReader (System.in));
y = Double.parseDouble(br3.readLine());
//Печать результата с вызовом функции
System.out.printf ("rezalt %f\n", ar.area(x, y));
}
if (l == 3){
//Ввод данных
BufferedReader br4 = new BufferedReader
(new InputStreamReader (System.in));
System.out.println ("Vvedite dlinu radiusa kruga\n\n");
r = Double.parseDouble(br4.readLine());
double r1 = r;
//Печать результата с вызовом функции
System.out.printf ("rezalt %f\n", ar.area(pi, r, r1));
}
if (l == 4){
System.out.println ("Vvedite dlinu trex storon treugolnika\n\n");
//Ввод данных
BufferedReader br6 = new BufferedReader
(new InputStreamReader (System.in));
x = Double.parseDouble(br6.readLine());
BufferedReader br7 = new BufferedReader
(new InputStreamReader (System.in));
y = Double.parseDouble(br7.readLine());
BufferedReader br8 = new BufferedReader
(new InputStreamReader (System.in));
z = Double.parseDouble(br8.readLine());
p = 0.5*(x+y+z);
//Печать результата с вызовом функции
System.out.printf ("rezalt %f\n", ar.area(p, x, y, z));
}
}
}
//Класс, где находятся наши методы
public class area_metods {
//Основной метод у нас всего один
//Мы переопределяем его столько раз, сколько нужно и так, как нам требуется
//Функция вычисления площади квадрата
double area(double x)
{
return (Math.pow(x, 2));
}
//Функция вычисления площади прямоугольника
double area(double x, double y)
{
return x*y;
}
//Функция вычисления площади круга
double area(double pi, double r, double r1)
{
return (pi*(r*r1));
}
//Функция вычисления площади треугольника
double area(double p, double x, double y, double z)
{
return (Math.sqrt(p*(p-x)*(p-y)*(p-z)));
Эдуард Трошин
Комментарии
Страницы
Ага. Я как-то обещал Вам встретиться у меня на рабхате. Не срослось -- Вы сами виноваты, не надо было хамить. А исходник какого-нито рабочего класса вышлю, давайте мыло. Тут я нервных клеток не теряю. И времени не займёт. :)
За 2,5 лет. Потом я сказал, что думаю о вашей "фигуре". Сами себе шлите свои классы. Болботунов кругом и так хватает, время только терять...
Неправда Ваша. Поначалу на меня свалилась куча работы, времени не стало, но потерпеть Вы не пожелали, стали обзываться.
Фиолетово.
>Поначалу на меня свалилась куча работы, времени не стало, но потерпеть Вы не пожелали
>За 2,5 лет.
Хм, mike хотел чтобы Петро терпел пару лет?
Логик, думай, как хошь.
>Логик, думай, как хошь.
Хм, mike НЕ хотел чтобы Петро терпел пару лет?
Но Петро терпел пару лет и потом всё сказал.
Хм, mike обиделся и сказал что пару лет это не так уж много терпеть?
Логик, тебе не о чём писать? Да, я пообещал встретиться с Трошиным за рюмкой чая. Но свалились командировки. Напряг. Он мог потерпеть пару-тройку недель. Но стал обзываться. Встреча потеряла смысл.
И ВООБЩЕ: Я НИКОМУ НИЧЕГО НЕ ОБЯЗАН.
Я не собака, которую ты изобразил.
>Я не собака, которую ты изобразил.
Да на фотке ты это типа "сосиска" то.
Сосиска или кусок гуано -- мне пофиг. Тебя чужие взаимоотношения колышут? Не переходи на личности.
>Сосиска или кусок гуано -- мне пофиг.
Да, как-бы это всё же разные сущности.
Страницы