Обратите внимание, что для сравнения объектов одного и того же класса нельзя использовать знак '='. В этом случае сравниваются адреса объектов. Для сравнения содержимого объектов в большинстве классов переопределяется метод equals.

В данном пакете содержится также класс String. Этот класс несколько отличается от других классов Java:

·  объекты класса String не обязательно создавать командой new. Допустима инициализация объекта константой:

String s="Изучаем Java";

или присвоение константы или другой строки:

String s1, s2;

s1="Изучаем Java";

s2=s1;

·  для объектов класса String переопределена операция '+', которая используется для конкатенации (сцепления) строк. Сцеплять можно не только строки, но и строку с числом, строку с булевской переменной и т. п. Если нужно сцепить строку с объектом, то для этого объекта должна быть переопределена функция toString, которая должна возвращать представление объекта в качестве строки. Например,

class Dog

{

public String Name;

public String Breed;

public String toString()

{

return ("Собака, имя: "+Name+",порода: "+Breed);

}

// ...

}

·  для строк реализована возможность разбиения на слова с помощью объекта класса StringTokenizer, который находится в пакете java. util.

Простой цикл разбиения строки на слова выглядит так:

String s="Изучаем язык Java! Очень интересно";

// создаем объект StringTokenizer. В конструктор передаем

// строку для разбиения и строку символов-разделителей

НЕ нашли? Не то? Что вы ищете?

StringTokenizer T=new StringTokenizer(s," ");

// пока будет найден следующий символ-разделитель

while(T. hasMoreTokens())

{

// выводим фрагмент строки до найденного разделителя

System. out. println(T. nextToken());

}

И, наконец, в пакете java. util есть несколько интересных классов для более сложных структур данных:

·  Date – дата;

·  Vector – вектор;

·  Stack – стэк;

·  Hashtable – хэш-таблица.

Задание для самостоятельной работы

Рассмотрите самостоятельно пакеты java. lang и java. util.

Операции Java

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

Операция

Название

Формат

.

Разделитель

Объект. Элемент

[]

Индекс

Массив[Индекс]

()

Вызов функции

Функция (Параметры)

++

Постфиксный инкремент

Переменная++

++

Префиксный инкремент

++Переменная

--

Постфиксный декремент

Переменная--

--

Префиксный декремент

--Переменная

~

Поразрядная инверсия

~Выражение

!

Логическое отрицание

!Выражение

instanceof

Проверка принадлежности объекта классу

Объект instanceof Класс

new

Выделение памяти

new тип

*

Умножение

Выражение * Выражение

/

Деление

Выражение / Выражение

%

Остаток от целочисленного деления

Выражение % Выражение

+

Сложение

Выражение + Выражение

-

Вычитание

Выражение – Выражение

<< 

Сдвиг влево

Выражение << Выражение

>> 

Сдвиг вправо

Выражение >> Выражение

>>> 

Сдвиг вправо с заполнением нулями

Выражение >>> Выражение

Меньше, чем

Выражение < Выражение

Больше, чем

Выражение > Выражение

<=

Меньше или равно

Выражение <= Выражение

>=

Больше или равно

Выражение >= Выражение

==

Сравнение на равенство

Выражение = = Выражение

!=

Сравнение на неравенство

Выражение!= Выражение

&

Побитовое "И"

Выражение & Выражение

^

Побитовое исключающее "ИЛИ"

Выражение ^ Выражение

|

Побитовое "ИЛИ"

Выражение | Выражение

&&

Логическое "И"

Выражение && Выражение

||

Логическое "ИЛИ"

Выражение || Выражение

? :

Условная операция

ЛогическоеВыражение ? ВыражениеЕслиИстина : ВыражениеЕслиЛожь

Операция=

Присваивание

Переменная*=Выражение
(вместо * может быть любая бинарная арифметическая или побитовая операция)

Задание для самостоятельной работы

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

Операторы Java

В Java используются те же операторы, что и в С++: if-else, while, do-while, for, switch-case, break, continue, return.

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

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

while (1)

{ }

В Java это выражение недопустимо, вместо него нужно использовать

while (true)

{ }

Во-вторых, в языке Java нет оператора goto.

Глава 2. Объектно-ориентированные принципы JAVA

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

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

Кроме того, существует возможность назначить права доступа к объектам класса и/или составным частям объектов. В языке Java существуют следующие модификаторы прав доступа:

public

общий доступ, для любых объектов и извне

private

частный доступ, только из методов данного класса

private protected

защищенный доступ, только из методов данного класса и его производных классов

Protected

защищенный доступ, из методов данного класса и его производных классов, а также из классов, определенных в том же пакете (каталоге)

По умолчанию переменные, методы и классы имеют тип protected.

Обращаться к переменным и методам объекта следует с помощью операции "точка", т. е.:

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

Если переменная или метод определены с ключевым словом static, это означает, что данная переменная или метод относится ко всему классу в целом, а не к объекту. Вызываются такие переменные и методы через имя класса:

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

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

final String s = "Изучаем Java";

так и в ходе выполнения:
final Date today = Date();

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

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

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

Если ни один конструктор не определен, компилятор создает конструктор по умолчанию – без параметров.

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

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

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

class Dog

{ public String Name;

public String Breed;

public int AverageWeight;

public int AverageHeight;

public void ShowDog(Graphics g, int x, int y)

{

g. drawString("Имя:"+Name, x, y);

g. drawString("Порода: "+Breed, x, y+20);

if (AverageWeight!=-1)

g. drawString("Вес:"+AverageWeight, x, y+40);

if (AverageHeight!=-1)

g. drawString("Рост:"+AverageHeight, x, y+60);

}

public Dog(String name, String breed,

int weight, int height)

{

Name=name;

Breed=breed;

AverageWeight=weight;

AverageHeight=height;

}

public Dog(String name)

{

Name=name;

Breed="Неизвестна";

AverageWeight=-1;

AverageHeight=-1;

}

}

В том случае, когда переменные имеют тип доступа private, к ним нельзя обращаться из других классов. Для таких переменных обычно определяют так называемые интерфейсные функции (set- и get-функции). Пусть, например, в определении класса "Собака" все переменные будут закрытые. Определим для них следующие методы:

class Dog

{ private String Name;

private String Breed;

private int AverageWeight;

private int AverageHeight;

public void setName(String Name)

{ this. Name=Name; }

public String getName()

{ return Name; }

public void setBreed(String Breed)

{ this. Breed=Breed; }

public String getBreed()

{ return Breed; }

public void setAverageWeight(int AverageWeight)

{ this. AverageWeight=AverageWeight; }

public int getAverageWeight()

{ return AverageWeight; }

public void setAverageHeight(int AverageHeight)

{ this. AverageHeight=AverageHeight; }

public int getAverageHeight()

{ return AverageHeight; }

...

}

Заметьте, что в Java, как и в С, используется ключевое слово this для явной ссылки на текущий объект.

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

Не менее важной характеристикой объектно-ориентированного языка программирования является наследование. Суть наследования состоит в создании производного класса, который имеет возможности базового класса плюс свои собственные возможности. Говорят, что производный класс расширяет (extends) базовый класс. Любой производный класс может расширять только один базовый класс. О модификаторах доступа – см. "Инкапсуляция".

Пусть базовый класс "Сотрудник" выглядит следующим образом:

class Employee

{

public Employee(String Name,

String Position, double Salary)

{

this. Name=Name;

this. Position=Position;

this. Salary=Salary;

}

public String ShowEmp()

{

return ("Служащий: " + Name +

" Должность: " + Position +

" Зарплата: " + Salary);

}

private String Name;

private String Position;

private double Salary;

}

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

Определим производный класс "Менеджер". Для вызова конструктора базового класса в производном классе используется ключевое слово super.

class Manager extends Employee

{

public Manager(String Name,

String Position, double Salary,

String Car, double Bonus, int StockOptions)

{

super(Name, Position, Salary);

this. Car=Car;

this. Bonus=Bonus;

this. StockOptions=StockOptions;

}

public String ShowManager()

{

return ("Автомобиль: " + Car +

" Надбавка: "+ Bonus +

" Количество акций: "+ StockOptions);

}

private String Car;

private double Bonus;

private int StockOptions;

}

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

super. имяФункции(параметры);

Абстрактные классы и интерфейсы

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

Определим абстрактный класс "Фигура".

abstract class Figure

{

public int x, y, width, height;

public Figure(int x, int y, int width, int height)

{

this. x=x;

this. y=y;

this. width=width;

this. height=height;

}

abstract double getArea();

abstract double getPerimeter();

}

Объекты абстрактного класса создавать нельзя. Сначала нужно определить производный класс, который расширяет абстрактный класс и предоставляет определения для его абстрактных методов. Определим производный класс "Круг" от класса "Фигура":

class Circle extends Figure

{

public double r;

public Circle(int x, int y, int width)

{

super(x, y, width, width);

r=(double)width / 2.0;

}

public double getArea()

{

return (r * r * Math. PI);

}

public double getPerimeter()

{

return (2 * Math. Pi * r);

}

}

Интерфейс в языке Java представляет собой "чисто абстрактный класс", т. е. класс, все методы которого являются абстрактными. Производный от интерфейса класс "раскрывает" (implements) интерфейс, предоставляя коды для всех его методов. Класс может расширять только один базовый класс, но раскрывать он может несколько интерфейсов.

Переменные интерфейса могут быть только static (т. е., переменные класса, а не объекта) и final (т. е., константы).

Для примера вместо абстрактного класса "Форма" определим интерфейс:

interface Shape

{

abstract double getArea();

abstract double getPerimeter();

}

Производный от него класс "Круг" будет выглядеть следующим образом:

class Circle implements Shape

{

public int x, y;

public double r;

public Circle(int x, int y, int r)

{

this. x=x;

this. y=y;

this. r=r;

}

public double getArea()

{

return (r * r * Math. PI);

}

public double getPerimeter()

{

return (2 * Math. Pi * r);

}

}

Как видим, производный класс наследует только поведение, так как интерфейс не может содержать свойства (т. е., переменные) объекта.

Полиморфизм

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


или динамическим связыванием).

Продолжим рассмотрение примера с геометрическими фигурами из прошлой темы. В нашем примере одна и та же переменная типа Figure (это абстрактный класс!) в зависимости от сгенерированной случайной величины может ссылаться как на объект производного класса Circle, так и на объект производного класса Square. В базовом классе заданы основные переменные и абстрактные методы – заготовки для будущего поведения объектов производных классов.

abstract class Figure

{

public int x, y, width, height;

public Figure(int x, int y, int width, int height)

{

this. x=x;

this. y=y;

this. width=width;

this. height=height;

}

abstract double getArea();

abstract double getPerimeter();

abstract void show(Graphics g);

}

Производные от базового класса Figure классы Circle и Square содержат свои дополнительные переменные и реализацию методов – собственно поведение объектов.

class Circle extends Figure

{

public double r;

public Circle(int x, int y, int width)

{

super(x, y, width, width);

r=(double)width / 2.0;

}

public double getArea()

{

return (r * r * Math. PI);

}

public double getPerimeter()

{

return (2 * Math. PI * r);

}

public void show(Graphics g)

{

g. setColor(Color. yellow);

g. fillOval(x, y,(int)(2*r),(int)(2*r));

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7