Управление выполнением программы 


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



ЗНАЕТЕ ЛИ ВЫ?

Управление выполнением программы



Логические операции

К логическим операциям относятся:

· отрицание (NOT)! (обозначается восклицательным знаком);

· конъюнкция (AND) & (амперсанд);

· дизъюнкция (OR) | (вертикальная черта);

· исключающее ИЛИ (XOR) ^ (каре).

Они выполняются над логическими данными, их результатом будет тоже логическое значение true или false. Законы этих операций показаны в табл. 1.1.

Таблица 1.1 Логические операции

b1 b2 !b1 b1&b2 b1|b2 b1^b2
true true false true true false
true false false false true true
false true true false true true
false false true false false false

Словами эти правила можно выразить так:

· отрицание меняет значение истинности;

· конъюнкция истинна, только если оба операнда истинны;

· дизъюнкция ложна, только если оба операнда ложны;

· исключающее ИЛИ истинно для различных операндов.

Кроме перечисленных четырех логических операций есть еще две логические операции сокращенного вычисления:

· сокращенная конъюнкция (conditional-AND) &&;

· сокращенная дизъюнкция (conditional-OR) ||.

Удвоенные знаки амперсанда и вертикальной черты следует записывать без пробелов.

Правый операнд сокращенных операций вычисляется только в том случае, если от него зависит результат операции, т. е. если левый операнд конъюнкции имеет значение true или левый операнд дизъюнкции имеет значение false.

Можно записывать выражения, не опасаясь деления на нуль:

(n!= 0) && (m/n > 0.001) или (n == 0) || (m/n > 0.001)

Примеры определения переменных целых типов:

byte b1 = 50, b2 = -99, bЗ;

short det = 0, ind = 1;

int i = -100, j = 100, k = 9999;

long big = 50, veryBig = 2147483648L;

char c1 = 'A', c2 = '?', newLine = '\n';

Операции над целыми типами

Все целочисленные операции, можно разделить на группы.

Арифметические операции

К арифметическим операциям относятся:

· сложение + (плюс);

· вычитание - (дефис);

· умножение * (звездочка);

· деление / (наклонная черта — слэш);

· взятие остатка от деления (деление по модулю) % (процент);

· инкремент (увеличение на единицу) ++;

· декремент (уменьшение на единицу) --.

Между сдвоенными плюсами и минусами нельзя оставлять пробелы. Сложение, вычитание и умножение целых значений выполняются как обычно, а вот деление целых значений в результате дает опять целое (так называемое "целое деление"), например, 5/2 даст в результате 2, а не 2.5, а 5/(-3) даст -1. Дробная часть числа попросту отбрасы­вается, происходит усечение частного, т.к. в Java принято целочисленное деление. Это странное для математики правило естественно для программирования: если оба операнда имеют один и тот же тип, то и результат имеет тот же тип. Достаточно написать 5/2.0 или 5.0/2 или 5.0/2.0 и получим 2.5 как результат деления вещественных чисел.

Операция деление по модулю определяется так:

а % b = а - (а / b) * b

Например, 5%2 даст в результате 1, а 5% (-3) даст, 2, т.к.

5 = (-3)*(-1) + 2, но (-5)%3 даст -2, поскольку -5 = 3 * (-1) - 2.

Операции инкремент и декремент означают увеличение или уменьшение значения переменной на единицу и применяются только к переменным, но не к константам или выражениям, нельзя написать 5++ или (а + b)++. Например, после приведенных выше описаний i++ даст -99, a j -- даст 99. Операции можно записать и перед переменной: ++i, — j. Разница проявится только в выражениях: при первой формe записи (постфиксной) в выражении участвует старое значение переменной и только потом происходит увеличение или уменьшение ее значения. При второй форме записи (префиксной) сначала изменится переменная, и ее новое значение будет участвовать в выражении.

 

Результат арифметической операции имеет тип int, кроме того случая, когда один из операндов типа long. В этом случае результат будет типа long.

Перед выполнением арифметической операции всегда происходит повышение (promotion) типов byte, short, char. Они преобразуются в тип int, а может быть, и в тип long, если другой операнд типа long. Операнд типа int повышается до типа long, если другой операнд типа long. Конечно, числовое значение операнда при этом не меняется.

Преобразования

Расширяется в Из Сужается в
short, int, long, float, double byte char
int, long, float, double short byte, char
int, long, float, double char byte, short
long, float, double int byte, short, char
float, double long byte, short, char, int
double float byte, short, char, int, long
- double byte, short, char, int, long, float

Операции сравнения

В языке Java шесть обычных операций сравнения целых чисел по величине:

· больше >;

· меньше <;

· больше или равно >=;

· меньше или равно <=;

· равно ==;

· не равно !=.

Сдвоенные символы записываются без пробелов, их нельзя переставлять местами, запись => будет неверной.

Результат сравнения будет иметь логическое значение: true для выражения 3!= 5; или false, например, для 3 == 5.

Для записи сложных сравнений следует использовать логичес­кие операции. Например, в вычислениях часто приходится делать проверки вида а < х < b. Подобная запись на языке Java приведет к сообщению об ошибке, поскольку первое сравнение а<х даст true или false, a Java не знает, больше это, чем b, или меньше. В данном случае следует написать выражение (а<х) && (х<b), причем здесь скобки можно опустить, написав а<х && х<b.

 

Во всем остальном вещественные типы — это обычные, вещественные значения, к которым применимы все арифметические операции и сравнения, перечисленные для целых типов. Характеристики вещественных типов приведены в табл. 4.

В языке Java взятие остатка*от деления %, инкремент ++ и декремент — применяются и к вещественным типам.

Таблица 4. Вещественные типы

Тип Разрядность Диапазон Точность
float   3,4е-38 < |х| < 3,4е38 7—8 цифр
double   1,7е-308<|х|<1,7е308 17 цифр

Примеры определения вещественных типов:

float х = 0.001, у = -34.789;

double 21 = -16.2305, z2;

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

· если в операции один операнд имеет тип double, то и другой приводится к типу double;

· если один операнд имеет тип float, то и другой приводится к типу float;

· в противном случае действует правило приведения целых значений.

К обычным вещественным числам добавляются еще три значения»:

1.Положительная бесконечность — POSITIVE_INFINITY, которая возникает при переполнении положительного значения, например, в результате операции умножения 3.0*6е307.

2. Отрицательная бесконечность — NEGATIVE_INFINITY.

3. "Не число", записываемое константой NaN (Not a Number), которое возни­кает при делении вещественного числа на нуль или умножении нуля на бесконечность.

Операции присваивания

Простая операция присваивания записывается знаком равенст­ва =, слева от которого стоит переменная, а справа выражение, совместимое с типом переменной:

х = 3.5, у = 2*(х - 0.567)/(х + 2), b = х<у, bb=х>=у&&b

Операция присваивания действует так: выражение, стоящее после знака равенства, вычисляется и приводится к типу переменной, стоящей слева от знака равенства. Результатом операции будет приведенное значение правой части.

Операция присваивания имеет еще одно побочное действие: переменная, стоящая слева, получает приведенное значение правой части, старое ее значение теряется.

В операции присваивания левая и правая части неравноправны, нельзя написать 3.5 = х. После операции х = у изменится переменная х, став равной у, а после у = х изменится у.

Кроме простой операции присваивания есть еще 11 составных операций присваивания (compound assignment operators):

+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= ; >>>=

 

Все составные операции действуют по одной схеме:

х ор= а э квивалентно х = (тип х), т. е. (х ор а).

Предположим, что переменная ind типа short определена со значением 1. Присваивание ind +=7.8 даст в результате число 8, то же значение получит и переменная ind. Эта операция эквивалентна простой операции присваивания ind=(short)(ind+7.8).

Перед присваиванием, при необходимости, автоматически производится приведение типа. Поэтому:

byte b = 1;

b = b + 10; // Ошибка!

b += 10; // Правильно!

Перед сложением b + 10 происходит повышение b до типа int, результат сложения тоже будет типа int и, в первом случае, не может быть присвоен переменной b без явного приведения типа. Во втором случае перед присваиванием произойдет сужение результата сложения до типа byte.

Приоритет операций

Ниже перечислены основные операции в порядке убывания приоритета, который сохраняетя на одной строке.

1. Постфиксные операции ++ и --.

2. Префиксные операции ++ и -- дополнение ~ и отрицание!.

3. Приведение типа (тип).

4. Умножение *, деление / и взятие остатка %.

5. Сложение + и вычитание -.

6. Сдвиги <<, >>, >>>.

7. Сравнения >, <, >=, <=.

8. Сравнения ==,!=.

9. Побитовая конъюнкция &.

10. Побитовое исключающее или ^.

11. Побитовая дизъюнкция |.

12. Конъюнкция &&.

13. Дизъюнкция ||.

14. Условная операция?:.

15. Присваивания =,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>=, >>>=.

Здесь перечислены не все операции языка Java.

Все операторы языка Java можно разделить на:

· операторы описания переменных и других объектов;

· операторы-выражения;

· операторы присваивания;

· условные операторы if;

· операторы циклов while, do-while, for;

· операторы варианта switch;

· Операторы перехода break, continue и return;

· блок {};

· пустые операторы — просто точка с запятой.

 

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

Блок

Блок может содержать в себе нуль или несколько операторов с целью их использования как одного оператора в тех местах, где по правилам языка можно записать только один оператор. Например, {х=5; у=?;}. Можно записать и пустой блок —{}.

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

Использование массивов

Для создания массива необходимо использовать квадратные скобки,

расположив, их справа от имени массива или от типа элементов, из которых

будет состоять массив, например:

int Numbers[];

int[] AnotherNumbers;

Допустимы оба варианта. При объявлении массивов в языке Java их

размер не указывается. Приведенные выше две строки не вызывают

резервирования памяти для массива. Здесь просто создаются ссылки на

массивы, которые нельзя использовать без инициализации.

Для того чтобы зарезервировать память для массива, необходимо создать

соответствующие объекты с помощью оператора new, например:

int[] AnotherNumbers; AnotherNumbers = new int[15];

 

В приведенной выше строке кода с помощью оператора new массиву AnotherNumbers выделяется память для хранения пятнадцати целых чисел. Нумерация элементов в массивах начинается с нуля.

Инициализацию элементов массива можно выполнить либо статически, либо динамически. В первом случае, инициализатор массива представляет собой список выражений разделенных запятыми и заключенный в фигурные скобки. Запятые отделяют друг от друга значения элементов массива. При таком способе создания массив будет содержать ровно столько элементов, сколько требуется для хранения значений, указанных в списке инициализации.

int[] ColorRed = {255, 255, 100, 0, 10};

В приведенной выше строке кода создается массив ColorRed из пяти элементов.

Динамическая инициализация выполняется с использованием индекса массива, например, в цикле:

int nInitialValue = 7; int[] AnotherNumbers;

AnotherNumbers = new int[15]; for(int i = 0; i < 15; i++)

{

AnotherNumbers[i] = nInitialValue;

}

Можно создавать массивы не только из переменных базовых типов, но и из произвольных объектов. Каждый элемент такого массива должен инициализироваться оператором new.

Массивы могут быть многомерными и несимметричными. В следующем примере создается массив массивов. В нулевом и первом элементе создается массив из четырех чисел, а во втором – из восьми:

int[][] nDim = new int[5][10]; nDim[0] = new int [4]; nDim[1] = new int [4]; nDim[2] = new int [8];

 

Приведенный ниже код создает традиционную матрицу из шестнадцати элементов типа double, каждый из которых инициализируется нулем. Внутренняя реализация этой матрицы – массив массивов типа double.

double matrix [][] = new double [4][4];

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

double matrix [][] = new double [4][]; matrix [0] = new double[4]; matrix[1] = new double[4];

matrix[2] = new double[4]; matrix[3] = { 0, 1, 2, 3 };

В следующем примере создается матрица размером 4 на 4 с элементами типа double, причем ее диагональные элементы (то есть, для которых х =у) заполняются единицами, а все остальные элементы остаются равными нулю.

class Matrix {

public static void main(String args[]) { double m[][];

m = new double[4][4]; m[0][0] = 1;

m[1][1] = 1; m[2][2] = 1; m[3][3] = 1;

System.out.println(m[0][0] +" "+ m[0][1] +" "+ m[0][2] +" "+ m[0][3]); System.out.println(m[1][0] +" "+ m[1][1] +" "+ m[1][2] +" "+ m[1][3]); System.out.println(m[2][0] +" "+ m[2][1] +" "+ m[2][2] +" "+ m[2][3]); System.out.println(m[3][0] +" "+ m[3][1] +" "+ m[3][2] +" "+ m[3][3]);

}

}

Виртуальная машина Java строго следит за тем, чтобы вы случайно не записали или не попытались получить значения, выйдя за границы массива. Если же вы попытаетесь использовать в качестве индексов значения, выходящие за границы массива – отрицательные числа, либо числа, которые больше или равны количеству элементов в массиве, то получите сообщение об ошибке.

Массивы в языке Java являются объектами встроенного класса. Для этого класса существует возможность определить размер массива, обратившись к элементу данных класса с именем length, например:

int[] AnotherNumbers;

AnotherNumbers = new int[15];

for(int i = 0; i < AnotherNumbers.length; i++)

{

AnotherNumbers[i] = nInitialValue;

}

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

 

public class lr1 {

//Объявление и инициализация массива int ar[][] = {{1,2,3,4,5},

{6,7,60,9,10},

{11,12,13,14,15}};

//Конструктор по умолчанию public lr1() {

}

//Метод, возвращающий максимальное значение массива public int getMax()

{

int max =0;

for(int i=0; i<3; i++)

{

for(int j=0; j<5; j++)

{

if (ar[i][j] > max) { max = ar[i][j]; }

}

}

return max;

}

public static void main(String[] args) { lr1 lr11 = new lr1();

System.out.println("Максимальное число =" + lr11.getMax());

}

}

 

 


 

 

Условные операторы if-else

В обобщенной форме этот оператор записывается следующим образом:

if (логическое выражение) оператор1; [ else оператор2;]

Раздел else необязателен. На месте «оператор1» или «оператор2» может стоять составной оператор, заключенный в фигурные скобки. «Логическое выражение» это любое выражение, возвращающее значение типа boolean.

Например,

int x;

if (x > 0) {

ProcessData();

x+= n;

} else

waitForMoreData();

Ниже приведена полная программа, в которой для определения, к какому времени года относится тот или иной месяц, используются операторы if-else.

class A

{

public static void main(String args[])

{

int month = 4;

String season ="зима";

if (month == 12 || month == 1 || month == 2) {

season = "зима";

} else if (month ==3 || month == 4 || month == 5) {

season = "весна";

} else if (month == 6 || month == 7 || month == 8) {

season = "лето";

} else if (month == 9 || month == 10 || month == 11) {

season = "осень";

}

System.out.println("Сейчас " + season + ".");

}

}

После выполнения программы вы должны получить следующий результат: Сейчас весна.

Оператор break

Этот оператор прекращает выполнение текущего блока и передает управление оператору, следующему за данным блоком. Для именования блоков в языке Java могут использоваться метки. Оператор break при работе с циклами и в операторах switch может использоваться без метки. В таком случае подразумевается выход из текущего блока. Можно использовать оператор break только для перехода за один из текущих вложенных блоков.

Например, в следующей программе имеется три вложенных блока, и у каждого своя уникальная метка. Оператор break, стоящий во внутреннем блоке, вызывает переход на оператор, следующий за блоком b. При этом пропускаются два оператора println.

Оператор switch

Оператор switch обеспечивает способ переключения между различными частями программного кода в зависимости от значения одной переменной или выражения. Общая форма этого оператора следующая:

switch (выражение) {

case значение 1:

break;

case значение 2:

break;

case значение n:

break;

default:

}

Результатом вычисления «выражения» может быть значение любого простого типа, при этом каждое из значений, указанных в операторах case, должно быть совместимо по типу с выражением в операторе switch. Все эти значения должны быть уникальными литералами. Если же вы укажете в двух операторах case одинаковые значения, тогда будет ошибка.

Если же значению выражения не соответствует ни один из операторов case, управление передается коду, расположенному после ключевого слова default. Отметим, что оператор default необязателен. В случае, когда ни один из операторов case не соответствует значению выражения и в switch отсутствует оператор default, выполнение программы продолжается с

оператора, следующего за оператором switch.

Внутри оператора switch (а также внутри циклических конструкций) break без метки приводит к передаче управления на код, стоящий после оператора switch. Если break отсутствует, после текущего раздела case будет выполняться следующий. Иногда бывает удобно иметь в операторе switch несколько смежных разделов case, не разделенных оператором break.

class SwitchSeason {

public static void main(String args[]) {

int month = 4;

String season;

switch (month) {

case 12:

case 1:

case 2:

season = "Зима";

break;

case 3:

case 4:

case 5:

season = "Весна";

break;

case 6:

case 7:

case 8:

season = "Лето";

break;

case 9:

case 10:

case 11:

season = "Осень";

break;

default:

season = "Неправильный номер месяца";

}

System.out.println("Апрель - это " + season + ".");

}

}

Ниже приведен пример, где оператор switch используется для передачи управления в соответствии с различными кодами символов во входной строке.

Программа подсчитывает число строк, слов и символов в текстовой строке.

class WordCount {

// Задаем текстовую строку

static String text = "Основы программирования\n" + "на языке Java\n" +

"для начинающих\n" + "разработчиков\n";

//Получаем длину строки

static int len;

public static void main(String args[]) {

len = text.length();

boolean inWord = false;

int numChars = 0; //переменная для хранения количества символов в тексте

int numWords = 0; //переменная для хранения количества слов в тексте

int numLines = 0; //переменная для хранения количества строк в тексте

//Организуем цикл по длине текстовой строки

for (int i=0; i < len; i++) {

char с = text.charAt(i); //Преобразуем элемент текстовой строки в символ

numChars++; //Увеличиваем на 1 счетчик символов

switch (с) { //Анализируем символы в текстовой строке

case '\n': numLines++; // Если символ перевода строки, то увеличиваем

//счетчик строк на 1

case '\t': // Тоже самое

case ' ': if (inWord) { //Если пробел увеличиваем счетчик слов на 1

numWords++;

inWord = false;

}

break;

default: inWord = true;

}

}

System.out.println("\t" + numLines +"\t" + numWords + "\t" + numChars);

//Выводим на консоль количество строк, слов и символов в текстовой строке

}

}

Оператор return

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

class ReturnDemo {

public static void main(String args[]) {

boolean t = true;

System.out.println("До оператора return"); //Перед оператором return

if (t) return;

System.out.println("”Это не выполнится"); //Это не будет выполнено

}

}

 

Циклы

Любой цикл можно разделить на 4 части – инициализацию, тело, итерацию и условие завершения. В Java есть три циклические конструкции:

while (с предусловием),

do-while (с постусловием)

for (с параметрами).

Оператор цикла while

Цикл такого типа многократно выполняется до тех пор, пока значение логического выражения равно true. Ниже приведена общая форма оператора while:

[ инициализация; ]

while (завершение) {

тело;

[итерация;] }

Инициализация и итерация необязательны. Ниже приведен пример цикла while для печати десяти строк «пример».

class WhileDemo {

public static void main(String args[]) {

int n = 10; while (n > 0) {

System.out.println("пример " + n); n--;

}

}

}

 

Оператор цикла do-while

Иногда возникает потребность выполнить тело цикла, по крайней мере, один раз – даже в том случае, когда логическое выражение с самого начала принимает значение false. Для таких случаев в Java используется циклическая конструкция do-while. Ее общая форма записи такова:

[ инициализация; ] do {

тело; [итерация;] }

while (завершение);

В следующем примере тело цикла выполняется до первой проверки условия завершения. Это позволяет совместить код итерации с условием завершения:

class DoWhile {

public static void main(String args[]) { int n = 10;

do {

System.out.println("пример " + n); } while (--n > 0);

}

}

 

Оператор цикла for

Общая форма записи оператора for следующая:

Оператор запятая

Иногда возникают ситуации, когда разделы инициализации или итерации цикла for требуют нескольких операторов. Поскольку составной оператор в фигурных скобках в заголовок цикла for вставлять нельзя, Java предоставляет альтернативный путь. Применение запятой (,) для разделения нескольких операторов допускается только внутри круглых скобок оператора for. Ниже приведен пример цикла for, в котором в разделах инициализации и итерации стоит несколько операторов.

class Comma {

public static void main(String args[])

{ int a, b;

for (a = 1, b = 4; a < b; a++, b--) {

System.out.println("a = " + a);

System.out.println("b = " + b); }

}

}

Вывод этой программы показывает, что цикл выполняется всего два раза.

а = 1 b = 4

а = 2 b = 3

Оператор continue

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

class ContinueDemo {

public static void main(String args[]) { for (int i=0; i < 10; i++) {

System.out.print(i + " "); if (i % 2 == 0) continue; System.out.println("");

}

}

}

Если индекс четный, цикл продолжается без вывода символа новой строки. Результат выполнения этой программы таков:

 

0 1

2 3

4 5

5 7

8 9

 

Как и в случае оператора break, в операторе continue можно задавать метку, указывающую, в каком из вложенных циклов вы хотите досрочно прекратить выполнение текущей итерации. Для иллюстрации служит программа, использующая оператор continue с меткой для вывода треугольной таблицы умножения для чисел от 0 до 9:

class ContinueLabel {

public static void main(String args[]) { outer: for (int i=0; i < 10; i++) {

for (int j = 0; j < 10; j++) {

if (j > i) { System.out.println(""); continue outer;

}

System.out.print(" " + (i * j));

}

}

}

}

Оператор continue в этой программе приводит к завершению внутреннего цикла со счетчиком j и переходу к очередной итерации внешнего цикла со счетчиком i. В процессе работы эта программа выводит следующие строки:

 

0 1

0 2 4

0 3 6 9

0 4 8 12 16

0 5 10 15 20 25

0 6 12 18 24 30 36

0 7 14 21 28 35 42 49

0 8 16 24 32 40 48 56 64

0 9 18 27 36 45 54 63 72 81

 

Классы

 

Базовым элементом объектно-ориентированного программирования в языке Java является класс. В этой главе Вы научитесь создавать и расширять свои собственные классы, работать с экземплярами этих классов и начнете использовать мощь объектно-ориентированного подхода. Напомним, что классы в Java не обязательно должны содержать метод main. Единственное назначение этого метода – указать интерпретатору Java, откуда надо начинать выполнение программы. Для того чтобы создать класс, достаточно иметь исходный файл, в котором будет присутствовать ключевое слово class, и вслед за ним — допустимый идентификатор и пара фигурных скобок для его тела.

 

class Point {

 

}

При этом имя исходного файла Java должно соответствовать имени хранящегося в нем класса. Регистр букв важен и в имени класса, и в имени файла.

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

 

class имя_класса extends имя_суперкласса { type переменная1_объекта:

type переменная2_объекта: type переменнаяN_объекта:

type имяметода1(список_параметров) { тело метода;

}

type имяметода2(список_параметров) { тело метода;

}

type имя методаМ(список_параметров) { тело метода;

}

}

Ключевое слово extends указывает на то, что «имя_класса» это подкласс класса «имя_суперкласса». Во главе классовой иерархии Java стоит единственный ее встроенный класс – Object. Если вы хотите создать подкласс непосредственно этого класса, ключевое слово extends и следующее за ним имя суперкласса можно опустить – транслятор включит их в ваше определение автоматически. Примером может служить класс Point, приведенный ранее.

 

Создание объекта класса

С помощью оператора new создается экземпляр указанного класса и возвращается ссылка на созданный объект. Ниже приведен пример создания и присваивание переменной р экземпляра класса Point.

 

Point р = new Point();

 

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

class TwoPoints {

public static void main(String args[]) { Point p1 = new Point();

Point p2 = new Point(); p1.x = 10;

p1.y = 20; р2.х = 42; р2.у = 99;

System.out.println("x = " + p1.x + " у = " + p1.y); System.out.println("x = " + р2.х + " у = " + р2.у);

} }

В этом примере используется класс Point. В классе TwoPoints создали два объекта этого класса Point, и их переменным х и у присвоены различные зна-чения. Таким образом, мы продемонстрировали, что переменные различных объектов независимы на самом деле. Ниже приведен результат, полученный при выполнении этой программы.

х = 10 у = 20

х = 42 у = 99

 

Объявление методов

Методы – это подпрограммы, присоединенные к конкретным определениям классов. Они описываются внутри определения класса на том же уровне, что и переменные объектов. При объявлении метода задаются тип возвращаемого им результата и список параметров. Общая форма объявления метода такова:

тип имя_метода (список формальных параметров) { тело метода;

}

Тип результата, который должен возвращать метод может быть любым, в том числе и типом void – в тех случаях, когда возвращать результат не требуется. Список формальных параметров – это последовательность пар тип-идентификатор, разделенных запятыми. Если у метода параметры отсутствуют, то после имени метода должны стоять пустые круглые скобки.

class Point { int х, у;

void init(int a, int b) {

х = а; y = b;

}

}

 

Вызов метода

В Java отсутствует возможность передачи параметров «по ссылке» на простой тип. В Java все параметры простых типов передаются «по значению», а это означает, что у метода нет доступа к исходной переменной, использованной

в качестве параметра. Заметим, что все объекты передаются по ссылке. Можно изменять содержимое того объекта, на который ссылается данная переменная.

 

Конструкторы

Инициализировать все переменные класса всякий раз, когда создается его очередной представитель – довольно утомительное дело даже в том случае, когда в классе имеются функции, подобные методу init. Для этого в Java предусмотрены специальные методы, называемые конструкторами. Конструктор – это метод класса, который инициализирует новый объект после его создания. Имя конструктора всегда совпадает с именем класса, в котором он расположен. У конструкторов нет типа возвращаемого результата – никакого, даже void. Заменим метод init из предыдущего примера конструктором.

class Point { int х, у;

Point(int х, int у) { this.x = х;

this.у = у;

}

}

 

class PointCreate {

public static void main(String args[]) { Point p = new Point(10,20);

System.out.println("x = " + p.x + " у = " + p.у);

}

}

 

Совмещение методов

Язык Java позволяет создавать несколько методов с одинаковыми именами, но с разными списками параметров. Такая техника называется совмещением методов (method overloading). В качестве примера приведена версия класса Point, в которой совмещение методов использовано для определения альтернативного конструктора, который инициализирует координаты х и у значениями по умолчанию (-1).

class Point { int х, у;

Point(int х, int у) { this.x = х;

this.у = у;

}

Point() { х = -1; у = -1;

}

}

class PointCreateAlt {

public static void main(String args[]) { Point p = new Point();

System.out.println("x = " + p.x + " у = " + p.y);

}

}

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

х = -1 у = -1

Решение о том, какой конструктор нужно вызвать в том или ином случае, принимается в соответствии с количеством и типом параметров, указанных в операторе new. Недопустимо объявлять в классе методы с одинаковыми именами и сигнатурами. В сигнатуре метода не учитываются имена формальных параметров, учитываются лишь их типы и количество.

Ссылка this в конструкторах

Очередной вариант класса Point показывает, как, используя this и со-вмещение методов, можно строить одни конструкторы на основе других.

class Point { int х, у;

Point(int х, int у) { this.x = х;

this.у = у;

}

Point() { this(-1, -1);

}

}

В этом примере второй конструктор для завершения инициализации объекта обращается к первому конструктору.

Методы, использующие совмещение имен, не обязательно должны быть конструкторами. В следующем примере в класс Point добавлены два метода distance. Функция distance возвращает расстояние между двумя точками. Одному из совмещенных методов в качестве параметров передаются координаты точки х и у, другому же эта информация передается в виде параметра-объекта Point.

class Point { int х, у;

Point(int х, int у) { this.x = х;

this. y = y;

}

double distance(int х, int у) { int dx = this.x - х;

int dy = this.у - у;

return Math.sqrt(dx*dx + dy*dy);

}

double distance(Point p) { return distance(p.x, p.y);

}

}

class PointDist {

public static void main(String args[]) {

Point p1 = new Point(0, 0); Point p2 = new Point(30, 40);

System.out.println("p1 = " + pi.x + ", " + p1.y); System.out.println("p2 = " + p2.x + ", " + p2.y); System.out.println("p1.distance(p2) = " + p1.distance(p2)); System.out.println("p1.distance(60, 80) = " + p1.distance(60, 80));

}

}

Обратите внимание на то, как во второй форме метода distance для получения результата вызывается его первая форма. Ниже приведен результат работы этой программы:

р1 = 0, 0 р2 = 30, 40

р1.distance(p2) = 50.0 p1.distance(60, 80) = 100.0

 

Наследование классов

 

Вторым фундаментальным свойством объектно-ориентированного под-хода является наследование. Классы-потомки имеют возможность не только создавать свои собственные переменные и методы, но и наследовать переменные и методы классов-предков. Классы-потомки принято называть подклассами. Непосредственного предка данного класса называют его суперклассом. В очередном примере показано, как расширить класс Point таким образом, чтобы включить в него третью координату z.

class Point3D extends Point { int z;

Point3D(int x, int y, int z) { this.x = x;

this.у = у; this.z = z;

}

Point3D() { this(-1,-1,-1);

}

}

В этом примере ключевое слово extends используется для того, чтобы сообщить транслятору, о намерении создать подкласс класса Point. Как видите, в этом классе не понадобилось объявлять переменные х и у, поскольку Point3D унаследовал их от своего суперкласса Point.

Ссылка super

В примере с классом Point3D частично повторялся код, уже имевшийся в суперклассе. Вспомните, как во втором конструкторе мы использовали this для вызова первого конструктора того же класса. Аналогичным образом ключевое слово super позволяет обратиться непосредственно к конструктору суперкласса.

class Point3D extends Point { int z;

Point3D(int x, int у, int z) {

super(x, y); // Здесь мы вызываем конструктор суперкласса this.z=z;

public static void main(String args[]) { Point3D p = new Point3D(10, 20, 30);

System.out.println(" x = " + p.x + " y = " + p.y + " z = " + p.z);

}

}

Вот результат работы этой программы: x = 10 у = 20 z = 30

 

Замещение методов

Новый подкласс Point3D класса Point наследует реализацию метода distance своего суперкласса (пример PointDist.java). Проблема заключается в том, что в классе Point уже определена версия метода distance(int х, int у), которая возвращает обычное расстояние между точками на плоскости. Мы должны заместить (override) это определение метода новым, пригодным для случая трехмерного пространства. В следующем примере проиллюстрировано и совмещение (overloading), и замещение (overriding) метода distance.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-26; просмотров: 186; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.135.197.201 (0.42 с.)