Шаг 7. Две программы

Сегодня я хочу остановиться на двух программах, выполняющих одно и то же действие — сортировку введенного с клавиатуры массива «пузырьковым методом». Однако несмотря на то, что они идентичны по функциональной нагрузке написаны они в двух разных парадигмах программирования. Первая демонстрирует процедурный подход, вторая — объектно ориентированный.  На самом деле это не совсем так, потому что в языке Java невозможно написать программу не используя ни единого класса и ни единого объекта. Раз так, любая программа на Java — объектно-ориентированная. Однако, речь идет о том, что даже создав фиктивный класс в Java, можно продолжать следовать свойственной для таких языков программирования как С, С++, Pascal, Basic и др. процедурной парадигме программирования. Использовать функции (методы), процедуры (методы типа void) и чувствовать себя так, как будто вы пишете не на Java. Именно такой подход рассматривается в первой программе. Во второй программе — во всей красе представлен объектно-ориентированный подход и содержится масса его особенностей.

Итак, первая программа:

package ru.ildwine.u;

import java.util.Scanner;

public class ArrayBubbleSorting {    

    public static void main(String[] args) {        
        int i, j, k;
        int[] a = new int[10];
        Scanner s = new Scanner(System.in);
        for (i = 0; i < 10; i++) {
            System.out.print("Введите " + i + " элемент массива: ");
            a[i] = s.nextInt();            
        }
        OutArray(a);
        for (i = 0; i < 10; i++) {             for (j = 9; j >= i; j--) {
                if (a[j] <= a[i]) {
                    k = a[i];
                    a[i] = a[j];
                    a[j] = k;
                }
            }
        }
        OutArray(a);
    }    

    static void OutArray(int[] b) {
        for (int c = 0; c < 10; c++) {
           System.out.print(b[c] + " "); 
        }
        System.out.println();
    }    
}

Как мы можем видеть программа состоит из одного единственного фиктивного класса с именем ArrayBubbleSorting. Класс содержит всего 2 метода. Первый метод public static void main(String[] args) {…} содержит все объявленные переменные и практически весь код программы, за исключением процедуры вывода массива на экран, которая выполняется во втором методе static void OutArray(int[] b) {…}.

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

Первое, на что хотелось бы обратить внимание, это статичность метода OutArray. Действительно, данный метод инициируется не в конструкторе класса, а в блоке статической инициализации. Статичный метод существует вне зависимости от того, создан ли хоть один экземпляр класса (вызовом конструктора класса). Таким образом, в данном примере мы обошлись использованием фиктивного класса и использованием двух его статичных методов ( OutArray и main).

Второе, на что я хочу обратить внимание, это отсутствие полей класса. Все переменные определены как локальные для метода main. В метод  OutArray, предназначенный для вывода нам приходится передавать массив как параметр. Это необходимо, так как метод  OutArray, не имеет доступа к локальным переменным метода main. Вы спросите, а почему бы не задать все переменные как поля класса, и тогда не будет необходимости в передаче параметров между методами? Вот! Именно поэтому мы рассмотрим вторую программу, в которой это реализовано. И увидим преимущество. А если рассмотреть этот пример, то создав в данном классе поля мы столкнемся с кучей проблем. Компилятор будет выдавать ошибки. Дело в том, что мы пытаемся получить доступ к нестатичным элементам класса. Поля класса у нас объявлены, но не инициализированны. Объект данного класса не создается вызовом конструктора. Альтернативный вариант, решающий эти трудности рассмотрен в нашей второй программе.

А теперь рассмотрим вторую программу:

package ru.ildwine.u;
import java.util.Scanner;

public class ArrayBubbleSorting2 {  

    final int n = 10;
    int i, j, k;
    int[] a;
    Scanner s;

    ArrayBubbleSorting2() {
        s = new Scanner(System.in);
        a = new int[n];
    }    

    void BubbleSorting() {
        for (i = 0; i < n; i++) {             for (j = n - 1; j >= i; j--) {
                if (a[j] <= a[i]) {
                    k = a[i];
                    a[i] = a[j];
                    a[j] = k;
                }
            }
        }
    }

    void InArray() {
        for (i = 0; i < n; i++) {
            System.out.print("Введите " + i + " элемент массива: ");
            a[i] = s.nextInt();            
        }
    }

    void OutArray() {
        for (i = 0; i < n; i++) {
           System.out.print(a[i] + " "); 
        }
        System.out.println();
    }

    public static void main(String[] args) {
        ArrayBubbleSorting2 z = new ArrayBubbleSorting2();        
        z.InArray();
        z.OutArray();
        z.BubbleSorting();
        z.OutArray();        
    }
}

Вторая программа построена по принципам объектно-ориентированного программирования. В программе определен главный класс ArrayBubbleSorting2. И вот здесь мы можем видеть новшества. Первое, что мы можем видеть — это блок описания полей класса:

final int n = 10;
int i, j, k;
int[] a;
Scanner s;

Здесь описаны поля, которые мы будем использовать в объектах нашего класса. Первое поле — это константа, как известно в Java константы определяются именно с помощью ключевого слова final перед типом данных. Вторая строчка объявляет 3 переменных типа int, необходимых для индексации и сортировки массива. Третья строчка объявляет массив, с которым мы будем работать. Ну и в последней строке мы объявляем переменную для работы с объектом класса Scanner, нужного нам для ввода значений с клавиатуры.

Далее мы видим описание методов класса. И в первую очередь конструктор класса:

ArrayBubbleSorting2() {
        s = new Scanner(System.in);
        a = new int[n];
}

Конструктор, будучи вызван в нашей программе, производит создание объекта класса, то есть выделяет память для хранения всех полей и методов экземпляра класса — объекта. Кроме того, он проводит инициализацию сканера и нашего рабочего массива, придавая последнему размерность.

Далее идет описание метода отвечающего за сортировку массива методом «пузырька»:

void BubbleSorting() {
        for (i = 0; i < n; i++) {             for (j = n - 1; j >= i; j--) {
                if (a[j] <= a[i]) {
                    k = a[i];
                    a[i] = a[j];
                    a[j] = k;
                }
            }
        }
    }

Мы не будем рассматривать алгоритм сортировки. Желающие могут найти его здесь. Мы остановимся на особенностях языка Java. Как мы видим метод имеет тип void. То есть не возвращает никакого значения. Также метод не принимает никаких входных параметров, о чём свидетельствуют пустые скобки после его названия. Это всё связано с тем, что метод работает с полями собственного класса (точнее объекта!). Все поля доступны всем методам внутри данного класса.

Далее описывается метод, отвечающий за ввод данных в массив:

void InArray() {
        for (i = 0; i < n; i++) {
            System.out.print("Введите " + i + " элемент массива: ");
            a[i] = s.nextInt();            
        }
}

Как мы можем видеть, данный метод также не принимает и не возвращает параметров. Данный метод в цикле выводит сообщение «Введите (i-й) элемент массива: « и ждет при этом ввода числа с клавиатуры, после чего, введенное значение присваивается элементу массива с индексом [i].

Метод вывода массива:

void OutArray() {
        for (i = 0; i < n; i++) {
           System.out.print(a[i] + " "); 
        }
        System.out.println();
}

Данный метод выводит содержимое массива на экран. Так же в цикле.

Итак, мы добрались до самого главного метода, который является точкой входа в нашу программу:

public static void main(String[] args) {
        ArrayBubbleSorting2 z = new ArrayBubbleSorting2();        
        z.InArray();
        z.OutArray();
        z.BubbleSorting();
        z.OutArray();        
}

Именно с этого метода запускается наша программа. В первой строке мы создаем объект z нашего текущего класса. И в последующих строках вызываем методы нашего объекта в следующем порядке : ввод, вывод, сортировка и снова вывод. Мы дважды вызываем метод OutArray, чтобы дважды вывести наш массив (до и после сортировки).

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

Продолжение следует

Комментарии для сайта Cackle