Программирование "без классов" на языке Java

Программировать без классов уже практически нельзя — это не модно, да и становится крайне тяжело, когда речь идет о сколько-нибудь приемлемом интерфейсе. Имейте в виду, что Java- приложение состоит из классов, где класс — это как функция в языке С или процедура в Delphi. Поэтому заголовок этого раздела не следует понимать буквально, а словосочетание "без классов" взято в кавычки. Разумеется, можно использовать консольные приложения, т. e. приложения без привычных нам окон. Но вот уже для работы с файлами или вывода на консоль вам понадобятся классы. В этом разделе мы намереваемся по возможности использовать в программе простые переменные. Например, мы хотели бы использовать операции:

X = 2;

y[0] = x – 1;

с переменными x и у и т. д., и т. п.

Итак, создадим простейшее Java-приложение, в котором запрашивается имя пользователя и выводится приветствие. Увы, для первого знакомства это приложение (листинг 1.1) не очень простое!

Листинг1.1. Приложение, выполняющее приветствие

import java.awt.*; import java.io.*; public class proba

static int b;

static String sname;

static char[] charray;

public static void main(String args[])

{

charray = new char[20]; int i=0;

// Вывод вопроса о вашем имени:

System.out.println("What is Your name?"); try {

while((b=System.in.read()) !=13)

{

charray[i++]=(char) b;}

}

catch(IOException e)

{

System.out.println("The error "+e);

}

sname=new String(charray);

//Вьшод строки приветствия:

System.out.println("Hello, fellow-programmer, "+sname);

}

}

Разберем приведенный в листинге код более подробно. Сначала идет подключение библиотек (библиотечных классов):

import java.awt.*; import java.io.*;

В языке С вы подключаете их с помощью инструкции #include. В Delphi вы используете команду use. Так что здесь нет ничего необычного. Дальше идет объявление класса (этого мы не избежали!):

public class proba {     }

Наш класс называется proba. Файл, где его следует сохранить, набрав текст программы в каком-нибудь редакторе (например, можно использовать Блокнот или встроенный редактор FAR manager, Norton Commander), также должен называться proba.java. Все же это еще не классы в традиционном смысле. Объявляем используемые переменные:

static int b; static String sname; static char[] charray;

Во всех языках программирования используются переменные разных типов. У нас это int, string и char (целое число, строка и символ соответственно). Слово static нам пришлось использовать, так как мы работаем с классами нетрадиционно, т. e. не создаем объекты этих классов. Итак, запомним, что если мы объявляем переменные класса и не создаем объектов класса, то переменные должны дополняться словом static. Наконец, добрались до единственного метода — main ():

public static void main(String args[])

{

charray = new char[20]; int i=0;

System.out.println("What is Your name?"); try{

while((b=System.in.read()) !=13)

{charray[i++]=(char) b; }

}

catch(IOException e)

{System.out.println("The error"+e);} sname=new String(charray);

System.out.println("Hello, fellow-programmer, "+sname);

}

Метод main() всегда объявляется так, как записано (запоминаем). Аргументы этого метода — параметры командной строки, использованной для запуска приложения. Пока что нам это не потребуется. Затем снова следует два объявления переменных:

// Объявляется массив символов, состоящий из 20 элементов: charray = new char[20]; int i=0;

Где слово static? Запомним, что внутри методов это слово использовать нельзя. Переменные класса должны объявляться вне методов, но внутри объявлений классов. Внутри методов объявляются локальные переменные методов.

Далее идет команда:

System.out.println("What is Your name?");

Эта команда, между прочим, использует имя класса System. Запомним эту команду для вывода строк на консоль. Результат ее действия мы вскоре увидим. А вот далее в цикле выполняется чтение символов до тех пор, пока не будет прочитан символ <Enter> (его код 13). Отсюда начинается то программирование "без классов", о котором мы и намеревались поговорить. Пока не будем "разжевывать" эту программу, но приведем на рис. 1.3 результат ее выполнения.

Рис. 1.3. Результатвыполнения программы, приведенной в листинге 1.1

Для того чтобы скомпилировать программу, используем командную строку MS-DOS:

javac proba.java

Программа javac — это и есть компилятор Java-nporpaMM. Чтобы ввести эту команду, например, из программы Norton Commander, наберите в командной строке >cmd.

Если ошибок нет, система создаст файл proba.class и разместит его в том же каталоге, где находится файл proba.java. Если файл proba.java лежит в каталоге, отличном от того, в котором размещен файл javac.exe, то следует указать путь к файлу proba.java, например:

javac c:\temp\proba.java (указан путь c:\temp\proba.java).

Запускаем класс на выполнение комавдой

java proba

(Найдите этот файл на рис. 1.3.)

Заметим, что если java.exe находится в каталоге, отличном от того, в котором расположен созданный нами класс proba.class, то следует предварительно выполнить команду:

set classpath=%classpath%;с:\temp\proba

Эту команду следует ввести из командной строки DOS; такую возможность предоставляет также, например, FAR manager или Norton Commander.

Теперь поговорим о программировании. Предполагается, что у вас уже есть кое-какой опыт, но, тем не менее, двигаемся все же с "нуля".

Традиционных команд сравнительно мало:

□               присваивание (=);

□               проверка условия (: -);

□               ЦИКЛЫ (for И while).

Существует еще команда goto, но в данном пособии ее практически не используем (как утверждают специалисты, про нее лучше забыть сразу, потому как в Java это ключевое слово зарезервировано, но самой комавды нет).

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

При написании кода вы работаете с именами переменных. Эти имена должны что-то выражать. Например, пусть требуется ввести какое-нибудь слово и подсчитать его длину (число символов). Обозначим это слово переменной siovo, объявим ее и присвоим ей значение пустой строки. Присваивание реализуется оператором = следующим образом: static String slovo="";

Теперь значение переменной siovo равно пустой строке "". Если вам не нравится пустая строка, то присвоим переменной siovo иное значение. Например:

slovo="yp-pa".

Длина слова возвращается в результате выполнения команды

slovo.length().

Поскольку метод System.in.read() читает байты (единицы информации, соответствующие символам строки, набираемым на клавиатуре), то объявляем массив байтов и создаем его в памяти:

static char[] charray = new char[20]; static int i=0;

Массив — это множество переменных; имена переменных совпадают с именем массива, но дополняются номерами (индексами). Например, charray[0] — первая переменная массива charray; charray[l] — вторая переменная массива charray и т. д. Создание массива выполняет комавда new, которая использует базовый тип (в данном случае char) и размерность массива (указывается в квадратных скобках).

Организуем цикл для чтения:

try{

while(( int b=System.in.read()) !=13)

{charray[i++]=(char) b;} //тело цикла }

Цикл while работает так. В скобках записывается условие, необходимое для его выполнения:

((int b=System.in.read()) !=13)

А именно, указывается, что ь = System.in.read(), а само проверяемое условие таково: ь != 13 (ь не равно 13). Если нажимаемая клавиша имеет код, отличный от 13, то символ попадает в массив charray в ячейку i и немедленно i увеличивается на 1 (это выполняется командой i++). Нам надо внимательно следить, чтобы число вводимых символов не превысило 20, так как мы объявили массив именно этого размера. Запомним, что любой цикл имеет тело. Тело цикла ограничивается фигурными скобками {…}, следующими сразу за условием цикла. То, что в них записывается, выполняется многократно, пока верно условие цикла. Выйти из цикла можно с помощью команды break. Итак, внутри нашего цикла считывается очередной символ с клавиатуры по команде:

int b=System.in.read().

Но значение считанного символа записывается в целую переменную ь. Конечно, вы знаете, что символы имеют свои числовые коды, представляемые байтами. Например, код пробела — 32. Однако при записи в массив charray числовой код преобразуется в настоящий символ, который данный код определяет. То, что выполняет команда charray[i++]=(char) b;

означает преобразование числа ь в соответствующий символ (char)ь (b и (char)ь, по суш. не одно и то же). Это и есть преобразование типов. В нашей программе мы еще раз используем преобразование типов при выводе строки на консоль:

// строка формируется из символов — представителей другого // типа:

slovo=new String(charray);

System.out.println("The word "+slovo+ " was read with length "+slovo.trim().length());

//выводим строку на консоль

Команда siovo.trim() . length () содержит две последовательно исполняемые операции: trim() — удаляет пробелы с начала и конца строки, и length () — возвращает длину строки.

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

Листинг1.2. Приложение, выполняющее подсчетдлины строки

import java.awt.*; // Подключаем библиотеки классов import java.io.*;

public class proba // Объявляем единственный класс

static int b; // Объявляем типы переменных класса static String slovo="";

// Объявляем массив символов и создаем пустой массив: static char[] charray=new char[20];

// Определяем единственный метод приложения: public static void main(String args[])

int i=0;    // Внутреннее объявление переменной i в методе

// main()

System.out.println("Input а word ->"); // Вывод строки

// с подсказкой

try

{

// Конструкция try catch используется для защиты,

// о чем будет рассказано позже

while((b=System.in.read()) !=13) // Организуемцикл,

// try пока не рассматриваем — это к циклу не имеет // отношения {

charray[i++]=(char) b; } // Тело цикла

}

catch(IOException e)

{

System.out.println("The error"+e);

}

// Преобразуем массив charray символов в строку slovo: slovo=new String(charray);

System.out.println("The word "+slovo+ " was read with length "+

slovo.trim().length()); // Вывод ответа

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

Теперь изменим несколько эту программу, чтобы в модифицированном виде она была бы применима для чтения двух чисел и отыскания их наибольшего общего делителя.

Чтение целого числа — это уже некоторая задача. Сначала покажем, как прочесть всего одно число (листинг 1.3).

ЛистинН.З. Приложение, выполняющее ввод числа с клавиатуры

import java.awt.*; import java.io.*; public class proba

static int b;

static String slovo="";

static char[] charray;

public static void main(String args[])

charray = new char[20]; // В массив попадают коды символов

// ‘0’..’9′

int i=0;

System.out.println("Input а number ->"); // Приглашение

// ввода числа

try

{ // Чтение символов числа выполняется в цикле:

while((b=System.in.read()) !=13) {charray[i++]=(char) b;

}

catch(IOException e)

{

System.out.println("The error"+e);

}

slovo=new String(charray); // В строке slovo — прочитанное

// число

System.out.println("The word "+slovo+ " was read with length"+slovo.trim().length());

double j=0; // Число j используем для преобразования в него // слова slovo // Тип double — это тип вещественного числа с фиксированной // точкой удвоенной точности int k=0;

int l=slovo.trim().length();

for(i=0;i<=(1-1); i++) // В этом цикле конструкция

// slovo.charAt(i) дает i-ый // символ слова slovo

{

switch(slovo.charAt(i)) // Формируем цифру k в зависимости

// от i-го символа слова slovo

{

case ‘0’: k=0; break; // если символ ‘0’, то полагаем

// k=0;

case ‘1’: k=l; break; // если символ ‘1’, то полагаем

// k=l;

case ‘2’: k=2; break; // если символ ‘2’, то полагаем

// k=2;

case ‘3’: k=3; break; // если символ ‘3’, то полагаем

// k=3;

case ‘4’: k=4; break; // если символ ‘4’, то полагаем

// k=4;

case ‘5’: k=5; break; // если символ ‘5’, то полагаем

// k=5;

case ‘6’: k=6; break; // если символ ‘6’, то полагаем

// k=6;

case ‘7’: k=7; break; // если символ ‘7’, то полагаем

// k=7;

case ‘8’: k=8; break; // если символ ‘8’, то полагаем

// k=8;

case ‘9’: k=9; break; // если символ ‘9’, то полагаем

// k=9;

default : k=0;break;

}

// Напомним, что 123=lxl02 + 2xl01 +Зх10и j=j+k*Math.pow(10,1—1—1) ;

// Поэтому преобразуем цифры к из слова в частичные суммы // kxlO1

// Функция Math.pow(x,y) вычисляет в Java число ху

}

System.out.println("The word "+slovo+ " was read with value "+ j) ;

// Результирующее число j выводим на консоль

}

}

В этой программе мы использовали цикл for и команду switch.

Цикл for применяется для повторения одного и того же блока операций (тела) фиксированное число раз:

for(i=0;i<=(l-l); i++)

{ тело цикла}

Переменная цикла i определяет номер итерации. Начальное значение i задает оператор i=o.

Условие i<= (i – i) проверяется перед каждым очередным прохождением цикла. Если условие истинно, то итерация цикла выполняется, если нет, то происходит выход из цикла.

Оператор i++ увеличивает номер переменной цикла на 1 после завершения очередной итерации. Наш цикл имеет такой вид:

for(i=0;i<=(l-l); i++)

// В этом цикле конструкция slovo.charAt(i) дает i-й символ // слова {

switch(slovo.charAt(i))

{

case ‘0’: k=0; break; // если символ ‘0’, то полагаем

// k=0;

case ‘1’: k=l; break; // если символ ‘1’, то полагаем

// k=l;

case ‘2’: k=2; break; // если символ ‘2’, то полагаем

// k=2;

case ‘3’: k=3; break; // если символ ‘3’, то полагаем

// k=3;

case ‘4’: k=4; break; // если символ ‘4’, то полагаем

// k=4;

case ‘5’: k=5; break; // если символ ‘5’, то полагаем

// k=5;

case ‘6’: k=6; break; // если символ ‘6’, то полагаем

// k=6;

case ‘7’: k=7; break; // если символ ‘7’, то полагаем

// k=7;

case ‘8’: k=8; break; // если символ ‘8’, то полагаем

// k=8;

case ‘9’: k=9; break; // если символ ‘9’, то полагаем

// k=9;

default : k=0;break;

}

Тело цикла начинается с оператора switch(siovo.charAt(i)). Этот оператор применяется для проверки значения i-го разряда слова siovo. Таким разрядом должна быть по нашему замыслу десятичная цифра 0..9. Какая именно цифра — устанавливает оператор case. Например, если цифраравна ‘5’ (в символьном представлении), то срабатывает оператор: case ‘5’ : k=5; break;

Следует обратить внимание на то, что break используется в операторе case для выхода из тела switch ()                                     {}, а не из цикла for, в

котором использована команда switch. Таким образом, команда switch позволяет присвоить переменной k значение (в числовом формате) i-ro разряда слова siovo, содержащего цифру в символьном формате (запомните, что 15′ и 5 — это не одно и то же!).

Теперь нетрудно понять логику нашего цикла for: на каждой итерации i читается очередной i-ый разряд слова siovo, выполняется его преобразование в числовое представление и к j добавляется величина k*Math.pow(io, i-i-i): j=j+k*Math.pow(10,l-i-1);

в соответствии с представлением десятичного числа, например:

123=1*102 + 2*101 +3*100. Команда Math.pow(10,l-i-l) ВЫ- числяет 10’^’^1.

Наконец, оператор if проверяет условие таким схематическим образом:

if (условие)

{ блок команд 1} else

{блок команд 2}

Проверяется условие, указываемое в скобках после слова if. Если оно истинно, то выполняется блок команд 1, иначе выполняется блок команд 2. С помощью оператора if можно проверять сложные логические условия. Например, следующий оператор: if( x>0) && (y>0)

{ A} else { B}

проверяет два условия: x>0 и y>0. Связка && соответствует логической операции И. Если оба условия истинны, то выполняется блок А, иначе (одно или оба условия ложны) — блок В.

Следующий оператор:

if ( x>0)   |      |      (y>0)

{ A} else { B}

выполняет проверку на истинность хотя бы одного условия: x>0 или y>o. Связка | | соответствует логической операции ИЛИ. Сложное условие, которое связывает с помощью связки ИЛИ несколько простых условий, истинно тогда и только тогда, когда истинно хотя бы одно простое условие.

В заключение этого раздела мы приводим расширенный текст программы (листинг 1.4), в результате выполнения которой считываются два целых положительных числа и возвращается их наибольший общий делитель. Пусть эти числа — А и В. Алгоритм такой:

Считать А;

Преобразовать А в число AA;

Считать В;

Преобразовать В в число BB; while (AA !=BB)

if (AA>BB)

AA=AA-BB; else if BB>AA BB=BB-AA;

Вывод на консоль AA;

Поскольку основные моменты были рассмотрены выше, то приводим код программы без комментариев.

Листинг 1.4. Отыскание наибольшего общего делителя двух чисел

import java.awt.*; import java.io.*;

public class proba {

static int b;

static String slovo="";

static char[] charray;

static char[] charrayl;

public static void main(String args[])

{

charray = new char[20]; int i=0;

System.out.println("Input a first number ->"); try{

while((b=System.in.read()) !=13)

{charray[i++]=(char) b; }

}

catch(IOException e)

{System.out.println("The error"+e);}

slovo=new String(charray);

double A=0;

double B=0;

int k=0;

int l=slovo.trim().length(); for(i=0;i<=(l-l); i++)

{

switch(slovo.charAt(i))

{

case ‘0’: k=0;break; case ‘1’: k=l;break; case ‘2’: k=2; break; case ‘3’: k=3;break; case ‘4’: k=4; break; case ‘5’: k=5; break; case ‘6’: k=6;break;

case ‘7’: k=7; break; case ‘8’: k=8;break; case ‘9’: k=9; break;

default : k=0;break;

}

A=A+k*Math.pow(10, l-i-1) ; }

charrayl = new char[20]; i=0;

System.out.println("Input a second number") try{

while((b=System.in.read()) !=13)

{charrayl[i++]=(char) b; }

}

catch(IOException e) {System.out.println("The error"+e);}

String slovol=new String(charrayl); k=0;

l=slovol.trim().length(); slovol=slovol.trim(); for(i=0;i<=(l-l); i++)

{

switch(slovol.charAt(i))

{

case ‘0’: k=0; break; case ‘1’: k=l; break; case ‘2’: k=2; break; case ‘3’: k=3; break; case ‘4’: k=4; break; case ‘5’: k=5; break; case ‘6’: k=6; break; case ‘7’: k=7; break;

case ‘8’: k=8; break; case ‘9’: k=9; break; default : k=0;break;

}

B=B+k*Math.pow(10, l-i-1) ; }

System.out.println("first is:"+ A); System.out.println("second is:"+ B); while (A!=B)

{

if (A>B)

A=A-B; else if (B>A)

B=B-A; else break;

System.out.println("Common devisor is: "+ А);//Вьшод // наибольшего общего делителя чисел А, В

Мы рассмотрели побайтовый ввод символов с клавиатуры. Однако имеется и более простая возможность. Для ее реализации следует воспользоваться стандартным классом BufferedReader (как видите, классы навязчиво предлагают себя в практике программирования). Следующий пример (листинг 1.5) осуществляет ввод строки, считываемой с клавиатуры с помощью класса BufferedReader.

Листинг1.5. Использование класса BufferedReader

import java.awt.*; import java.io.*; public class keyb

static String slovo="";

public static void main(String args[])

{

// Создаем переменную кеуЫ для чтения строки с клавиатуры;

BufferedReader keybl = new BufferedReader(new InputStreamReader(System.in));

// Класс BufferedReader предоставляет возможность читать // строки с помощью метода readLine();

System.out.println("What is Your name ?");// Просим ввести имя try{

slovo=keybl.readLine(); } // Читаем строку slovo с клавиатуры; catch (Exception e)

U

//Вывод приветствия на консоль

System.out.println("Hellow, fellow-programmer "+slovo); try{ System.in.read();

}

catch(Exception e)

U

}

}

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

Источник: Герман О. B., Герман Ю. О., Программирование на Java и C# для студента. — СПб.: БХВ-Петербург, 2005. — 512 c.: ил.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100