Главная » Java, Web » Классы и объекты java

0

Класс описывается с использованием слова class. Простейший пример описания класса:

class UserData {

static String name; static int age;

Kiiacc — это тип, наподобие таких типов, как int и boolean. Имя класса используется для объявления типов переменных. Например, можно описать переменную std, указав ее тип как тип student: Student std;

При этом мы имеем в виду, что класс student описан в следующем виде:

class Student {

String name;                 // имя студента

double testl, test2, test3; // оценки за три теста double getAverage() {  // средняя оценка

return (testl + test2 + test3)/3;

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

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

Сам объект может быть создан при помощи следующей инструкции:

std = new Student();

Эта инструкция создает объект класса student и помещает ссылку на этот объект в переменную std. Значение переменной — это ссылка на объект, но не сам объект. К свойствам объекта можно обратиться, указав их имена следующим образом:std.name, std.testl, std.test2, std.test3.

Пример

System.out.println("Hello, " + std.name + ". Your test grades are:"); System.out.println(std.testl); System.out.println(std.test2) ; System.out.println(std.test3);

System.out.println("Srednyaya otsenka " + std.getAverage());

Переменная, тип которой задается с указанием имени класса, может содержать нулевую ссылку, которая записывается как "null":

std = null;

Проверка того, является ли ссылка на объект нулевой, осуществляется при помощи такой конструкции

if (std == null) … Рассмотрим еще один пример.

Пример

Student std, stdl, // объявляем четыре переменных

std2, std3; // типа Student std = new Student(); // создаем новый объект,

// принадлежащий классу Student // сохраняем ссылку на объект в переменной std stdl = new Student(); // создаем второй объект класса Student

// сохраняем ссылку на этот объект //в переменной stdl std2 = stdl;      // Копируем ссылку на объект stdl

//в переменную std2 std3 = null; // сохраняем нулевую ссылку на объект

// в переменной std3 std.name = "John Smith"; // задаем значения некоторых переменных stdl.name = "Mary Jones";

После выполнения этих инструкций память компьютера можно изобразить с помощью рисунка (рис. П4.6).

Рис. П4.6. Схема памяти компьютера

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

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

Если переменная содержит ссылку на объект, который описан при помощи final (то есть, после инициализации переменные никогда не могут быть изменены), то это вовсе не значит, что данные, которые хранятся в объекте, не могут быть изменены. Неизменна только лишь ссылка на объект. Например, следующая конструкция будет вполне верной: final Student stu = new Student();

stu.name = "John Doe"; // изменяем данные в объекте

/ / значение в stu не изменяется

При этом интересно сравнить результат работы следующих двух фрагментов кода (табл. П4.2).

Таблица П4.2. Сравниваем код

Инициализация объектов. Конструкторы

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

Переменная экземпляра класса может быть инициирована во время своего объявления. Например, рассмотрим класс PairOfDice. Объект этого класса содержит две переменные:

public class PairOfDice {

public int diel =3; // первая кость public int die2 =4; // вторая кость public void roll() {

// выбрасываем кости и выбираем случайное чило от 1 до 6 diel = (int) (Math, random() *б) + 1; die2 = (int) (Math, random() *6) + 1;

}

}

Здесь переменные diel и die2 инициализированы значениями 3 и 4 соответственно. Эта инициализация производится в момент создания объекта PairOfDice. Может существовать много объектов типа PairOfDice. Каждый раз, когда создается объект такого типа, в нем инициализируются указанные переменные с заданными начальными значениями. Вместо наперед заданных фиксированных значений переменные объекта могут быть инициализированы случайными числами: public class PairOfDice {

public int diel = (int) (Math.random()*6) + 1;

public int die2 = (int) (Math.random()*6) + 1;

public void roll() {

diel = (int) (Math, random() *6) + 1;

die2 = (int) (Math, random() *6) + 1;

} }

Объект создается при помощи оператора new. Если в программе создается объект PairOfDice, то мы пишем:

PairOfDice dice;         // Объявление переменной с типом PairOfDice.

dice = new PairOfDice(); // создание нового объекта

Инструкция new PairOfDice () выделяет память, в которой будет храниться объект, в переменной dice будет храниться ссылка на этот объект. Часть инструкции, используемой для создания объекта, выглядит как вызов функции PairOfDice (). Это обращение к специальному типу функций, который представляет собой конструктор. Может показаться странным то, что в классе мы нигде не создавали такой функции, так откуда она взялась? Дело в том, что каждый класс имеет конструктор. Если программист не создаст конструктор сам, то автоматически будет создан конструктор по умолчанию. Такой конструктор производит самые необходимые действия.

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

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

Пример класса с конструктором с заданными параметрами                                                 I

public class PairOfDice {

public int diel; // первая кость public int die2; // вторая кость public PairOfDice(int vail, int val2) { // создает две кости

// устанавливая их значения равными vail и val2 diel = vail; // присваивает значения die2 = val2; // переменным

public void roll() {

// бросаем кости и выбираем случайные числа от 1 до 6 diel = (int) (Math, random()*6) + 1; die2 = (int) (Math, random() *6) + 1;

После того как мы вставили такой конструктор в описание класса PairOfDice, мы больше не можем создать объект, написав инструкцию new PairOfDice (). Система использует конструктор по умолчанию только в том случае, если в классе не описан конструктор в явном вице. Наш конструктор имеет два параметра. Однако эта проблема легко решается. Мы имеем возможность создать еще один конструктор в этом же классе. Этот конструктор буцет отличаться тем, что в нем будет присутствовать иное число параметров.

Пример с двумя конструкторами

public class PairOfDice    {

public int diel; //    первая кость

public int die2; //    вторая кость public PairOfDice() {

roll о ;

public PairOfDice(int vail, int val2) {

// Конструктор. Создает пару костей по заданным значениям. diel = vail; // присваивает конкретные значения переменным die2 = val2;

public void roll() { // Бросает кости // случайные числа от 1 до 6 diel = (int) (Math, random()*6) + 1; die2 = (int) (Math, random() *6) + 1;

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

new PairOf Dice () , либо new PairOfDice (x, у) , где x И у имеют ТИП int.

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

Программа полностью

public class RollTwoPairs {

public static void main(String[] args) {

PairOfDice firstDice; // первая пара костей

firstDice = new PairOfDice();

PairOfDice secondDice; // вторая пара костей

secondDice = new PairOfDice();

int countRolls; // сколько раз бросали

// первую и вторую пару костей int totall;     // для первой пары костей

int total2;          // для второй пары костей

countRolls = 0;

do { // Бросаем две пары костей, пока сумма не совпадет firstDice.roll(); // бросаем первую пару totall = firstDice.diel + firstDice.die2; // сумма

System.out.printIn("First pair comes up " + totall); secondDice.roll(); // бросаем вторую пару total2 = secondDice.diel + secondDice.die2; // сумма System.out.printIn("Second pair comes up " + total2); countRolls++; // считаем броски System.out.printIn(); // пустая строка } while (totall != total2); System.out.println("Bylo " + countRolls +

" broskov do sovpadeniya cummy.");

}

}

В отличие от обычной функции, конструктор может быть вызван только с использованием оператора new в такой форме:

new class-name (parameter-list) Список параметров может быть пустым.

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

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

Перепишем класс student, используя в нем конструктор, а переменную name определим как private, public class Student {

private String name;                    // имя студента

public double testl, test2, test3; // оценки за три теста Student(String theName) {

// конструктор объектов Student; // с заданием имени студента

name = theName; }

public String getName() {

// метод для чтения значения защищенного

// свойства — переменной name return name;

}

public double getAverage() {

// сосчитать среднюю оценку

return (testl + test2 + test3) / 3; }

}

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

std = new Student("John Smith"); stdl = new Student("Mary Jones");

Поскольку имя name было объявлено защищенным, т. е. private, мы не сможем изменить это имя и даже прочитать его напрямую извне класса. Чтобы найти и прочитать имя, используется метод getNameO, его можно вызывать и извне класса. Это позволяет быть уверенным в том, что после создания объекта student в нем будет хранится одно и то же имя, которое не может быть изменено.

Источник: Будилов В. А. Интернет-программирование на Java. — СПб.: БХВ-Петербург, 2003. — 704 е.: ил.

По теме:

  • Комментарии