Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Java.doc
Скачиваний:
11
Добавлен:
20.04.2019
Размер:
936.45 Кб
Скачать

If (условие) {

операторы1;

} else {

операторы2;

}

Оператор цикла с предусловием

while (условие) оператор;

или

while (условие) {

операторы;

}

Оператор цикла с постусловием

do оператор; while (условие);

или

do {

операторы;

} while (условие);

Оператор цикла с параметром

for(список1;условие;список2) оператор;

или

for(список1;условие;список2) {

операторы;

}

Операторы управления итерациями

оператор прекращения цикла

break;

оператор перехода к следующей итерации

continue;

Оператор выбора

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

case константа1: оператор1;

case константа2: оператор2;

case константа3: оператор3;

. . .

default: оператор;

}

Выражение может иметь любой целочисленный тип, кроме long (byte, short, int, char)

Константы в операторе выбора играют роль меток, т.е. указывают на точки входа. У одной точки входа может быть несколько меток-констант.

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

case константа1:

case константа2:

case константа3: оператор;

После входа выполняются операторы до конца всей конструкции.

Для выхода из конструкции следует использовать break.

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

case константа1: оператор1; break;

case константа2: оператор2; break;

case константа3: оператор3; break;

Массивы и строки

В языке Java массивы и строки являются специальными видами объектов.

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

объявление массивов;

создание массивов;

Кроме того, дополнительно может выполняться инициализация массивов.

Объявление массивов

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

тип имя[];

или

тип[] имя;

При объявлении массива создается лишь ссылочная переменная.

При объявлении одного массива обе записи эквивалентны.

Различия проявляются при объявлении нескольких переменных:

int a[],b,c; – массив и две переменных

или

int[] a,b,c; – три массива

Создание массивов

Массивы создаются в динамически распределяемой памяти по команде вида:

new тип [размер];

Ссылку на созданный массив нужно присвоить ранее объявленному объекту, например:

a=new int[25];

При создании массива все его элементы получают нулевое значение.

Инициализация массивов

Инициализация массива (т.е. присваивание начальных значений) может выполняться как при объявлении:

тип имя[] = {список значений};

так и при создании массива:

имя=new тип[] {список значений};

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

Индексы элементов массива начинаются с 0.

Для определения количества элементов в массиве можно использовать поле length.

Типичная циклическая конструкция по обработке элементов массива:

S=0;

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

S+=A[i];

}

Для обработки всех элементов массива может использоваться специальная форма записи цикла for, не содержащая в явном виде параметра цикла:

for(тип имя : массив) {

операторы;

}

Например:

S=0;

for(double element : A) {

S+=element;

}

Операции над массивами

– присваивание: a=b; при присваивании копируется ссылка, т.е. обе переменных будут ссылаться на один и тот же массив;

– сравнение: a==b или a!=b сравниваются ссылки на массивы, т.е. два массива равны, если это один и тот же массив;

– освобождение ссылки: a=null; если на массив отсутствуют другие ссылки, то он (когда-нибудь) уничтожается

Двумерные (многомерные) массивы

Для объявления двумерных массивов используется аналогичный синтаксис: тип имя[][]; или тип[][] имя;

Кроме того, любой двумерный массив может рассматриваться как массив, состоящий из нескольких одномерных массивов: тип[] имя[];

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

// объявление двумерного массива int mas2D[][];

// создание прямоугольного массива mas2D=new int [N] [M];

// создание треугольного массива mas2D=new int [N] []; for(int i=0;i<N;i++) mas2D[i]=new int[i+1];

При инициализации двумерных массивов необходимо сгруппировать элементы, образующие отдельные строки:

mas2D = new int [] [] { {1}, {2,3}, {4,5,6} };

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

Пример 1. Сумма элементов двумерного массива

S=0; for ( int i=0 ; i<mas2D.length ; i++ ) for ( int j=0 ; j<mas2D[i].length ; j++ ) S+=mas2D[i][j];

Пример 2. Вывод двумерного массива

for ( int[] mas1D : mas2D ) { for ( int element : mas1D ) System.out.print(element+" "); System.out.println(); }

Строки

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

Любые строковые константы, встречающиеся в тексте программы, фактически рассматриваются как ссылки на объекты этого класса.

Соответственно, используя строковые константы, можно вызывать любые методы класса String.

Для внутреннего представления строк используется двухбайтовая кодировка Unicode.

Это обеспечивает переносимость программ.

Все объекты-строки являются неизменяемыми, т.е. у строк отсутствуют методы, позволяющие модифицировать их внутреннее представление.

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

Основные методы класса String

int length() получение длины строки: int n = str.length();

char charAt(int индекс) получение одного символа из указанной позиции: char c = str.charAt(i);

String substring(int индексОт, int индексДо) получение копии части строки: String str2 = str.substring(i,i+k);

Пример. Подсчет частоты вхождения символа в строку

String str="обороноспособность";

char c='о';

int n=0;

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

if ( c==str.charAt(i) ) n++;

boolean equals(String строка) сравнение строк if ( str1==str2 ) if ( str1.equals(str2) )

int compareTo(String строка) лексикографическое сравнение строк if ( str1<str2 ) if ( str1.compareTo(str2)<0 )

boolean equalsIgnoreCase(String строка) сравнение строк без учета регистра

int compareToIgnoreCase(String строка) лексикографическое сравнение строк без учета регистра

Пример. Аутентификация пользователя

if ("admin".equalsIgnoreCase(user)

&& "q1G#bas.8".equals(password) )

{

System.out.println("Добро пожаловать!");

}

else

{

System.out.println("Посторонним вход запрещен!");

}

boolean contains(String подстрока) содержит ли строка заданную подстроку?

boolean startsWith(String подстрока) начинается ли строка на заданную подстроку?

boolean endsWith(String подстрока) заканчивается ли строка на заданную подстроку?

Пример. Определение рода прилагательного

String sex="неизвестный";

if ( prilag.endsWith("ый") || prilag.endsWith("ий") )

sex="мужской";

if ( prilag.endsWith("ая") || prilag.endsWith("яя") )

sex="женский";

if ( prilag.endsWith("ое") || prilag.endsWith("ее") )

sex="средний";

System.out.println("Прилагательное " + prilag + " имеет " + sex +" род");

int indexOf(Char символ)

int indexOf(Char символ, int индексОт) определяет первую позицию заданного символа в строке

int indexOf(String подстрока)

int indexOf(String подстрока, int индексОт) определяет первую позицию заданной подстроки в строке

Если символ или подстрока не найдены, методы возвращают число -1.

int lastIndexOf(Char символ)

int lastIndexOf(Char символ, int индексДо) определяет последнюю позицию заданного символа в строке

int lastIndexOf(String подстрока)

int lastIndexOf(String подстрока, int индексДо) определяет последнюю позицию заданной подстроки в строке

Если символ или подстрока не найдены, методы возвращают число -1.

Пример. Извлечение текста из скобок

nachalo=stroka.indexOf( '(' );

konec=stroka.indexOf( ')', nachalo );

String text=stroka.substring(nachalo+1,konec);

(Пример требуется дополнить необходимыми проверками!)

String trim() возвращает копию строки, не содержащую начальных и конечных пробелов

String toLowerCase() возвращает копию строки в нижнем регистре

String toUpperCase() возвращает копию строки в верхнем регистре

Часто требуется получить строковое представление для значений примитивных типов. Для этого используются статические методы класса String:

String String.valueOf (boolean b)

String String.valueOf (char c)

String String.valueOf (int i)

String String.valueOf (long l)

String String.valueOf (float f)

String String.valueOf (double d)

За обратное преобразование отвечают статические методы классов-оболочек примитивных типов:

boolean Boolean.parseBoolean (String s)

byte Byte.parseByte (String s)

short Short.parseShort (String s)

int Integer.parseInt (String s)

long Long.parseLong (String s)

float Float.parseFloat (String s)

double Double.parseDouble (String s)

Если задано неверное представление величины, эти методы порождают исключительную ситуацию.

Пример 1. Преобразование строки в число

int chislo = Integer.parseInt (stroka);

Пример 2. Преобразование числа в строку

String stroka = String.valueOf(chislo);

Класс StringBuilder

Класс StringBuilder также используется для представления объектов-строк.

Некоторые методы класса StringBuilder совпадают с классом String: length(), charAt(), indexOf() и т.д.

Класс StringBuilder имеет расширенную по сравнению с классом String функциональность, поскольку объекты этого класса могут изменяться.

Все методы класса StringBuilder, изменяющие объект, возвращают ссылку на этот же объект.

Благодаря этому можно использовать цепочки вызовов:

объект.метод1(…).метод2(…).метод3(…);

вместо

объект.метод1(…);

объект.метод2(…);

объект.метод3(…);

StringBuilder append(что) используется для добавления к объекту других строк и строковых представлений значений примитивных типов (13 вариантов)

StringBuilder sb=new StringBuilder();

sb.append("Число равно ").append(x);

Метод append() неявно используется при склеивании строк:

String s = "Число равно "+x;

ß

String s = new StringBuilder("Число равно ")

.append(x)

.toString();

StringBuilder insert(int индекс, что) используется для вставки в строку других строк и строковых представлений значений примитивных типов (12 вариантов)

StringBuilder sb=new StringBuilder( "(,)" );

sb.insert(2,y);

sb.insert(1,x);

delete(int индексОт,int индексДо) используется для удаления части строки

StringBuilder sb=new StringBuilder( "корова" );

sb.delete(3,5);

replace(int индексОт,int индексДо,String подстрока) используется для замены части строки на заданную подстроку

StringBuilder sb=new StringBuilder( "корова" );

sb.replace(3,6,"ыто");

StringBuilder deleteCharAt(int индекс) используется для удаления символа в указанной позиции

StringBuilder setCharAt(int индекс,char символ) используется для замены символа в указанной позиции

StringBuilder sb=new StringBuilder( "маруся" );

sb.setCharAt(0,'п');

sb.deleteCharAt(5);

Объектно-ориентированное программирование

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

Основная идея ООП заключается в том, что программа представляется в виде совокупности взаимодействующих между собой объектов.

Каждый объект содержит набор данных, которые определяют текущее состояние объекта.

Взаимодействие между объектами происходит путем передачи сообщений.

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

Набор действий, который объект может выполнить, определяет поведение объекта.

Набор данных, описывающий состояние объекта, и набор действий, описывающих поведение объекта, определяют тип объекта.

В языке Java объектные типы данных принято называть классами.

Синтаксис описания классов

[доступ] class ИмяКласса

[extends ИмяСуперКласса]

[implements СписокИнтерфейсов] {

// описание полей и методов класса

}

Синтаксис описания полей

[доступ] [модификаторы] ИмяТипа имяПоля = Значение;

Типы доступа

private доступ разрешен только из методов данного класса

protected доступ разрешен только из методов данного класса и его подклассов

public доступ разрешен из методов любых классов

нет обозначения доступ разрешен из методов классов из текущего пакета

Виды модификаторов

static данное поле является общим для всех экземпляров класса (переменная класса)

final значение данного поля не может быть изменено

Комбинация этих двух модификаторов (final static) обычно используется для описания констант.

Пример. Описание класса «Точка».

class Point {

double x;

double y;

}

В языке Java классы относятся к ссылочным типам данным. Это значит, что все для работы с объектами простого описания полей или переменных недостаточно.

Обязательно нужно создать объект:

имяПеременной = new ИмяТипа(параметры);

Например:

Point A;

A = new Point();

или

Point B = new Point();

Для уничтожения объекта достаточно освободить ссылку:

A = null;

Для доступа к полям и методам объекта используется оператор . (точка):

имяПеременной . имяПоля

или

имяПеременной . имяМетода (параметры)

Например:

A.x = 5;

A.y = 7;

Синтаксис описания методов

[доступ] [модификаторы]

ВозвращаемыйТип имяМетода ( [СписокПараметров] )

[throws СписокИсключений] { 

// тело метода

}

В языке Java тело метода всегда записывается внутри описания класса!

Типы доступа те же самые, что и у полей

Виды модификаторов

static действие метода не зависит от конкретного объекта (метод класса)

final данный метод не может быть переопределен в подклассах

Для доступа к статическим полям и методам объекта (переменным класса и методам класса) используется следующий синтаксис:

ИмяКласса . имяПоля

или

ИмяКласса . имяМетода (параметры)

Например:

Math.PI

String.valueOf(…)

Внутри метода для доступа полям и методам текущего объекта может быть использован идентификатор this:

this . имяПоля

или

this . имяМетода (параметры)

Для возвращения значения из метода используется оператор return:

return выражение;

Если метод не должен возвращать значение, в заголовке метода вместо возвращаемого типа должно указываться ключевое слово void.

Пример. Описание класса «Отрезок».

class Segment {

Point p1;

Point p2;

Point getMidpoint() {

Point p = new Point();

p.x = (p1.x+p2.x)/2;

p.y = (p1.y+p2.y)/2;

return p;

}

}

Инкапсуляция

Принцип инкапсуляции означает, что доступ извне к состоянию объекта ограничивается или запрещается.

Взаимодействие с объектом должно осуществляться исключительно (или почти исключительно) путем передачи сообщений (вызовов методов).

В языке Java для реализации принципа инкапсуляции используется ограничение доступа в комбинации со специальными видами методов, называемых getter'ами и setter'ами.

Типичные getter'ы и setter'ы выглядят так:

private Тип поле;

public Тип getПоле() { return поле; }

public void setПоле(Тип поле) { this.поле=поле; }

Пример. Getter'ы и setter'ы для класса «Точка».

public double getX() {

return x;

}

public void setX(double x) {

this.x=x;

}

public double getY() {

return y;

}

public void setY(double y) {

this.y=y;

}

Многие Java-технологии (технология разработки компонентов JavaBeans, технологии объектно-реляционного отображения баз данных и др.) в обязательном порядке требуют наличия getter'ов и setter'ов в проектируемых классах.

Большинство интегрированных сред разработки Java-приложений содержат возможность автоматической генерации getter'ов и setter'ов только на основании описания полей

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

Общий вид конструктора:

public ИмяКласса ( [Список параметров] ) {

// тело конструктора

}

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

Пример. Возможные конструкторы класса «Точка».

public Point() {

x=0;

y=0;

}

public Point(double x, double y) {

this.x = x;

this.y = y;

}

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

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

public Point() {

x=0;

y=0;

}

ß

public Point() {

this(0,0);

}

Пример. Реализация метода getMidpoint с использованием getter'ов и конструктора

public Point getMidpoint() {

return new Point( ( p1.getX()+p2.getX() )/2,

( p1.getY()+p2.getY() )/2 );

}

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

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

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

Принцип наследования позволяет поэтапно строить классы от простого к сложному.

Для реализации наследования в языке Java используется ключевое слово extends ("расширяет"):

class НовыйКласс extends СтарыйКласс {

// описание новых полей и методов

}

Пример. Иерархия классов, описывающая пользователей

public class User {

private String login;

private String password;

// …

}

public class Student extends User {

private String group;

// …

}

public class Teacher extends User {

private String chair;

// …

}

Принято исходный (базовый, родительский) класс называть суперклассом, вновь созданный класс (производный, дочерний) – подклассом.

Открытые (public) и защищенные (protected) поля и методы суперкласса становятся открытыми и защищенными полями и методами подкласса.

По умолчанию суперклассом любого класса является класс Object.

Класс Object содержит в своем составе 11 методов, например:

String toString() получить текстовое представление объекта

boolean equals(Object obj) проверить эквивалентность двух объектов

public int hashCode() вычислить хэш-код объекта

При наследовании конструкторы суперкласса в подклассе не сохраняются!

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

Кроме того, в первой команде каждого конструктора подкласса необходимо с помощью ключевого слова super записывать вызов конструктора суперкласса.

Пример. Вызов конструктора суперкласса

class Point3D extends Point {

private double z;

public Point3D(double x, double y, double z) {

super(x,y);

this.z = z;

}

// ...

}

Единственная ситуация, в которой разрешается не записывать вызов конструктора суперкласса – это если в суперклассе имеется конструктор без параметров (конструктор по умолчанию).

В этом случае вызов конструктора суперкласса происходит неявно.

Например, такое происходит когда класс описывается без использования ключевого слова extends (т.е. суперклассом является класс Object).

Полиморфизм

Наследование тесно связано с еще одним принципом ООП – полиморфизмом.

В соответствии с принципом полиморфизма вместо объекта суперкласса может быть использован объект любого его подкласса.

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

Пример. Использование полиморфизма при присваивании

User u;

Student s = new Student("n2008999","12345","П22");

Teacher t = new Teacher("kuntsevich","***","ПМиМ");

u=s; // Ok!

u=t; // Ok!

s=u; // Ошибка!

t=u; // Ошибка!

Пример. Использование полиморфизма при вызове метода

Point3D p1 = new Point3D(x1,y1,z1);

Point3D p2 = new Point3D(x2,y2,z2);

// вызов конструктора: Segment(Point p1,Point p2);

Segment s = new Segment(p1,p2);

Абстрактные классы

При построении иерархий классов часто нет необходимости (а иногда и невозможно) описывать некоторые методы суперклассов.

В подобных случаях используют абстрактные классы, которые содержат абстрактные методы (методы, которые объявлены, но не реализованы).

Каждый абстрактный метод должен быть перегружен в подклассе.

При описании абстрактного класса сам класс и требуемые методы помечаются ключевым словом abstract:

abstract class ИмяКласса {

abstract Тип имяМетода( [список параметров] );

// ...

}

Тело у абстрактного метода отсутствует!

Объекты абстрактных классов создавать нельзя, но можно создавать объекты подклассов, в которых абстрактные методы перегружены.

Пример. Абстрактная геометрическая фигура и прямоугольник.

abstract class Figure {

abstract double getArea();

}

class Rectangle extends Figure {

private double a,b;

double getArea() {

return a*b;

}

// ...

}

Интерфейсы

Дальнейшим обобщением абстрактных классов являются интерфейсы – ссылочные типы данных, содержащие только абстрактные методы и поля-константы.

Объявление интерфейса

[public] interface ИмяИнтерфейса

[extends СписокИнтерфейсов]

{

// объявление полей интерфейса

// объявление методов интерфейса

}

При объявлении интерфейса все методы автоматически рассматриваются как абстрактные, а все поля – как константы. Все элементы интерфейса по умолчанию имеют область видимости public.

Примеры. Интерфейсы для геометрических фигур

public interface PointInterface {

double getX();

double getY();

}

public interface AreaInterface {

double getArea();

}

При объявлении классов список интерфейсов указывается после ключевого слова implements ("реализует"):

class ИмяКласса implements СписокИнтерфейсов {

// ...

}

Пример. Класс "Точка"

public class Point implements PointInterface {

private double x;

private double y;

public double getX() {

return x;

}

public double getY() {

return y;

}

}

Пример. Класс "Окружность"

public class Circle extends Point

implements AreaInterface {

private double r;

public double getArea() {

return Math.PI*r*r;

}

}

Различия между классами и интерфейсами

1. Нельзя создать объект типа "интерфейс" (но можно переменной типа "интерфейс" присваивать ссылку на объект любого класса, реализующего этот интерфейс)

PointInterface p1 = new Point(x,y);

PointInterface p2 = new Circle(x,y,r);

2. В интерфейсах не может быть конструкторов (они могут быть только в классах)

3. Элементы интерфейса всегда имеют область видимости public (другие модификаторы указывать запрещается)

4. Интерфейс может расширять сразу несколько предков-интерфейсов (класс может расширять только один класс)

5. Реализация методов интерфейсов может присутствовать только в классах (интерфейсы всегда остаются абстрактными)

Пакеты

Каждое Java-приложение в своем составе может содержать десятки и даже сотни классов.

В сложных проектах возможно дублирование имен классов, например:

Table – класс, описывающий таблицу

или

Table – класс, описывающий мебель (стол)

Также возможно совпадение имени пользовательского класса с именем библиотечного класса.

Для упрощения и упорядочения работы с большим количеством классов, в языке Java используются пакеты.

Пакеты имеют иерархическую структуру, соответствующую структуре каталогов, и являются аналогами пространств имен (namespace) в языке C++.

Благодаря пакетам каждый класс, кроме собственно имени, получает полное (уточненное) имя, отличающее его от других одноименных классов.

Для указания принадлежности класса (классов) к какому-либо пакету используется директива package:

package имя.пакета;

public class ИмяКласса {

// ...

}

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

Полное (уточненное) имя класса состоит из имени пакета и имени класса, например:

java.io.File класс, описывающий файл, из пакета java.io

java.util.Date класс, описывающий дату, из пакета java.util

java.sql.Date класс, описывающий дату, из пакета java.sql

java.awt.Point класс, описывающий точку, из пакета java.awt

Пример. Использование уточненных имен классов

// создание файла

java.io.File file;

file = new java.io.File("s:/myfile.txt");

// создание текущей даты

java.util.Date date;

date = new java.util.Date();

// создание точки

java.awt.Point point;

point = new java.awt.Point(x,y);

В качестве имени пакета компанией Sun рекомендуется использовать доменное имя сайта, записанное в обратном порядке. Это гарантирует уникальность имени пакета во всем мире, например:

com.sun.media.sound пакет компании Sun для работы со звуком

org.w3c.dom.html пакет организации World Wide Web Consortium для работы с языком HTML

org.netbeans.modules.image пакет Netbeans для работы с изображениями

В некоторых случаях разрешается использовать краткие имена классов:

– для классов из пакета java.lang, например:

String или Integer

вместо вместо

java.lang.String java.lang.Integer

– для классов из текущего пакета

При необходимости использовать краткие имена для классов из других пакетов, требуется их перечислить в директиве import:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]