Слайд 1Программирование на Java
Тема 2.1 Классы и объекты
Слайд 2 Терминология ООП
Инкапсуляция (encapsulation) – это объединение данных и
операций над ними и сокрытие данных от пользователя объекта.
Концепция
расширения класса для создания нового называется наследованием (inheritance).
Способность объектной переменной ссылаться на объекты, имеющие разные фактические типы, называется полиморфизмом (polymorphism).
Слайд 3 Терминология ООП
Объектно-ориентированное программирование (ООП) стало доминирующей парадигмой программирования, вытеснив
"структурные", процедурно-ориентированные способы программирования, разработанные в начале 70-х годов. Язык
Java представляет собой полностью объектно-ориентированный язык.
Традиционное структурное программирование заключается в разработке набора функций (алгоритмов) для решения поставленной задачи. Определив эти функции, программист должен задать подходящий способ хранения данных. Т. е. сначала решался вопрос, как манипулировать данными, а затем – какую структуру применить для организации этих данных. ООП изменило порядок этих действий на противоположный, поместив на первое место данные и сделав алгоритмы, предназначенные для их обработки, второстепенным вопросом.
В ООП любая программа состоит из объектов. Основной принцип, обеспечивший высокую производительность ООП, заключается в том, что каждый объект предназначен для выполнения определенных задач. Если перед объектом стоит задача, для решения которой он не предназначен, у него должен быть доступ к другому объекту, который может решить эту задачу. Доступ к другому объекту осуществляется путем вызова метода этого объекта. Это – обобщенный вариант вызова функций, применяемого в процедурном программировании.
Объект не должен непосредственно манипулировать внутренними данными другого объекта, а также предоставлять другим объектам прямой доступ к своим данным. Все связи между ними обеспечиваются с помощью вызова методов.
Основными элементами программы являются классы. Класс – это тип данных, по которому создается объект. Внутри класса находится описание данных и алгоритмов для работы с ними. Создание объекта на основе некоторого класса называется созданием экземпляра (instance) этого класса.
Слайд 4 Терминология ООП
Инкапсуляция (encapsulation) – это ключевое понятие при работе
с объектами. Формально инкапсуляция – это объединение данных и операций
над ними и сокрытие данных от пользователя объекта. Данные объекта называются полями экземпляра (instance fields), а функции и процедуры, выполняющие операции над данными, – его методами (methods). В указанном объекте, т. е. экземпляре класса, поля экземпляра имеют определенные значения. Множество этих значений называется текущим состоянием (state) объекта. Применение любого метода к какому-нибудь объекту может изменить его состояние.
Еще раз подчеркнем, что основной принцип инкапсуляции заключается в запрещении прямого доступа к полям экземпляра данного класса методам других классов. Программы должны взаимодействовать с данными объекта только с помощью методов этого объекта.
Объект также характеризуется понятиями поведения (behavior) и сущности (identity).
Поведение объекта определяется методами, которые можно вызвать. Все объекты, являющиеся экземплярами одного и того же класса, ведут себя одинаково.
Сущность объекта определяется тем, чем данный объект отличается от других, характеризующихся таким же поведением и состоянием. Индивидуальные объекты, представляющие собой экземпляры класса, всегда отличаются своей сущностью и обычно отличаются своим состоянием.
Класс можно сконструировать на основе других классов. В этом случае говорят, что вновь созданный класс расширяет класс, на основе которого он реализован. Язык Java, по существу, создан на основе "глобального суперкласса", называемого Object. Все остальные объекты расширяют его.
Новый класс содержит все свойства и методы расширяемого класса, а также новые методы и поля данных. Концепция расширения класса для создания нового называется наследованием (inheritance).
Способность объектной переменной (т. е. переменной типа “объект”) ссылаться на объекты, имеющие разные фактические типы, называется полиморфизмом (polymorphism).
Слайд 5 Классы
Определение класса (без указания модификаторов доступа):
class
имя_класса [extends имя_суперкласса]
{ тип переменная1_объекта [= значение]; // Поля тип переменная2_объекта
[= значение]; // класса тип переменнаяN_объекта [= значение];
имя_класса() {} // Конструктор по умолчанию
имя_класса(список_параметров) // Конструктор
{ тело метода; }
тип имя_метода1(список_параметров)
{тело метода; }
тип имя_метода2(список_параметров)
{тело метода;}
тип имя_методаN(список_параметров)
{тело метода;}
}
Слайд 6 Классы
Класс в Java является основным программным элементом, а
так же класс – это описание нового типа данных. Во
главе иерархии классов языка Java стоит главный базовый класс (суперкласс , родительский класс) – Object. Если слово extends отсутствует, то по умолчанию создаваемый класс является производным классом (подклассом, классом потомком) класса Object.
Данные включаются в класс путем объявления переменных между открывающей и закрывающей фигурными скобками, выделяющими в определении класса его тело. Эти переменные объявляются точно так же, как объявляются локальные переменные. Единственное отличие состоит в том, что их надо объявлять вне методов, в том числе вне метода main. Чтобы не нарушить инкапсуляции данных, поля нужно объявлять с модификатором private.
Тип результата, который должен возвращать метод, может быть любым, в том числе и типом void – в тех случаях, когда возвращать результат не требуется. Список параметров – это последовательность пар тип – идентификатор, разделенных запятыми. Если параметры у метода отсутствуют, то после имени метода должны стоять пустые круглые скобки.
Параметры методу в языке Java передаются только по значению. Термин вызов по значению (call by value) означает, что метод получает именно значение, переданное ему вызывающим модулем. (В противоположность этому, вызов по ссылке (call by reference) означает, что метод получает от вызывающего модуля адрес (location) переменной.)
В языке Java метод не может модифицировать значение переменной, переданной ему по значению. Если же методу передается значение ссылки на объект, он может модифицировать поля объекта (т. е. изменить состояние объекта), на который указывает ссылка, но не может изменить значение ссылки и переназначить ее на новый объект.
Еще раз:
Метод не может изменить параметры основных типов (т. е. числа и булевские значения).
Метод может изменить состояние объекта, передаваемого по значению ссылки на объект.
Метод не может изменить значение ссылки на объект и переназначить ее на новый объект.
Слайд 7 Классы и объекты
Пример программы:
class Dog
{
private int age; // возраст
private
String name; // кличка
public int getAge() { return age; }
public String getName() {return name;}
public void setAge(int newAge)
{ if (newAge < 0)
System.out.println("Как это понимать? Собака еще не родилась?");
else if (newAge > 30)
System.out.println("Они столько не живут");
else age = newAge;
}
public void setName (String newName){name = newName;}
public void voice()
{ for (int i = 1; i <= age; i++)
System.out.println("гав-гав");
}
}
Слайд 8 Классы и объекты
class NewDog
{ public static
void main (String args [])
{ Dog dog1 =
new Dog();
dog1.setAge(4);
dog1.setName("Жучка");
dog1.voice();
}
}
Слайд 9 Классы и объекты
Объект в Java , как и в
других языках программирования, это переменная, имеющая тип класс, т. е.
объект является экземпляром класса.
Операция new создает объект указанного класса в динамической памяти и возвращает ссылку на вновь созданный объект.
Операция точка используется для доступа к переменным и методам объекта.
Опишем для примера класс Dog (собака). У него будет два поля: кличка и возраст. При описании поведения собаки в этом простом примере ограничимся лаем. Конечно, лаять по-настоящему наша собака не будет (ведь это всего лишь программная конструкция), она будет выводить в консоль «гав-гав». Чтобы было интереснее, предположим, что все собаки, с которыми имеет дело наша программа, умны настолько, что когда их вынуждают лаять, они говорят «гав-гав» столько раз, сколько им лет.
Инкапсуляция означает сокрытие деталей реализации класса. Класс разделяется на две части: внутреннюю и внешнюю. Внешняя часть (интерфейс) тщательно продумывается исходя из того, каким образом могут взаимодействовать с объектами данного класса другие объекты программы. Внутренняя часть закрыта от посторонних, она нужна только самому классу для обеспечения правильной работы открытых методов.
Например, в классе Dog есть целочисленное поле age (возраст). Можно оставить его открытым, тогда его при необходимости можно будет изменить простым присваиванием (очень удобно). Но при этом ничто не мешает присвоить этому полю заведомо некорректное значение (например, 666 или -5 или 3000). Это может произойти из-за ошибки в программе. Или, к примеру, пользователь вводит возраст собаки в текстовое поле, а программа присваивает его в ответ на нажатие кнопки (и пользователь может ошибиться). Это нежелательный случай. Лучше сделать поле age закрытым (private) и добавить два открытых метода: getAge() и setAge(). Первый метод будет просто возвращать значение скрытого поля. Второй метод позволит задать новый возраст собаки, производя при этом проверку присваиваемого значения.
Слайд 10 Классы и объекты
В исходном файле может быть только один
открытый (т. е. public) класс и сколько угодно классов с другими спецификаторами
доступа. Имя файла должно совпадать с именем открытого класса.
В каждом классе может присутствовать свой метод main (что позволяет протестировать каждый класс отдельно), однако выполняется метод main только того класса, имя которого указано в командной строке виртуальной машины Java (например, C:\>java NewDog).
Классы программы могут содержаться в разных файлах. Их можно откомпилировать по отдельности, а можно указать компилятору имя основного класса (в данном примере – C:\>javac NewDog.java). В последнем случае компилятор, обнаружив, что в классе NewDog используется класс Dog, будет искать класс Dog.class. Если он его не найдет, то автоматически будет найден и скомпилирован файл Dog.java. Справедливо и более общее утверждение: если версия обнаруженного файла Dog.java создана позже, чем существующий файл Dog.class, компилятор языка Java автоматически перекомпилирует файл класса. Другими словами в компиляторе Java уже встроены возможности утилит типа make.
Слайд 11 Пример использования существующих классов
Пример :
GregorianCalendar now =
new GregorianCalendar();
int month = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_WEEK);
…
GregorianCalendar dateX
= new GregorianCalendar();
dateX.set(Calendar.YEAR, 2010);
dateX.set(Calendar.MONTH, Calendar.APRIL);
dateX.set(Calendar.DAY, 15);
dateX.set(2010, Calendar.APRIL, 15);
…
dateX.add(Calendar.MONTH, 3); // Отодвинуть момент dateX на 3
// месяца
Слайд 12 Пример использования существующих классов
Стандартная библиотека языка Java содержит
два отдельных класса для отслеживания моментов времени: класс Date, определяющий
момент времени, и класс GregorianCalendar, расширяющий класс Calendar, который описывает свойства календаря в целом. Оба класса отсчитывают время в миллисекундах с 1 января 1970.
Класс GregorianCalendar позволяет вычислить атрибуты указанного момента времени, например, дату, день недели, месяц или год. Чтобы получить одно из этих значений, можно использовать метод get. Чтобы выбрать желаемый атрибут, нужно передать методу константу, определенную в классе Calendar, например, Calendar.MONTH или Calendar.DAY_OF_WEEK (пример).
Состояние объекта можно изменить с помощью метода set (пример).
Существует метод, позволяющий установить год, месяц и день с помощью одного вызова (пример).
К заданной дате можно добавить n-е количество дней, недель, месяцев и т.д.
Ниже приведена программа, иллюстрирующая работу класса GregorianCalendar. Программа выводит на экран календарь текущего месяца.
Класс GregorianCalendar позволяет легко создавать программы для работы с календарем. Программист не обязан знать о том, как именно класс GregorianCalendar вычисляет месяцы и дни недели. Нужно лишь использовать методы класса get, set и add.
Основное предназначение этой программы – показать, как можно использовать интерфейс класса для выполнения сложных задач, не вникая в детали его реализации.
Слайд 13 Пример использования существующих классов
import java.util.*;
public class CalendarTest
{
public static void main(String[] args)
{ // Создаем
объект d с текущей датой,
// при этом объект d также наследует константы
// и методы класса Calendar
GregorianCalendar d = new GregorianCalendar();
int today = d.get(Calendar.DAY_OF_MONTH);
int month = d.get(Calendar.MONTH);
int g = d.get(Calendar.YEAR);
System.out.print(today + " ");
System.out.print(month + 1 + " ");
System.out.println(g + "\n");
// Устанавливаем объект d на первую дату месяца
d.set(Calendar.DAY_OF_MONTH, 1);
int weekday = d.get(Calendar.DAY_OF_WEEK);
// Выводим на печать заголовок таблицы
System.out.println("Bc Пн Вт Ср Чт Пт Сб");
// Выводим первую строку календаря
for (int i = Calendar.SUNDAY; i < weekday; i++)
System.out.print(" ");
Слайд 14 Пример использования существующих классов
do {
// Выводим на печать день
int day = d.get(Calendar.DAY_OF_MONTH);
if (day < 10) System.out.print(" ");
System.out.print(day);
// Отметить текущий день звездочкой
if (day == today)
System.out.print("*");
else
System.out.print(" ");
// После каждой субботы начинаем новую строку
if (weekday == Calendar.SATURDAY)
System.out.println();
// Передвинуть объект d на новый день
d.add(Calendar.DAY_OF_MONTH, 1);
weekday = d.get(Calendar.DAY_OF_WEEK);
}
while (d.get(Calendar.MONTH) == month);
// Цикл завершается, когда объект d установлен
// на первый день следующего месяца
Слайд 15 Пример использования существующих классов
// Выводим на экран последнюю строку
if(weekday
!= Calendar.SUNDAY)
System.out.println();
}
}
Слайд 16 Конструкторы
Пример 1:
import java.util.*;
public class Student
{
private
String name; // Имя студента
private Date mDay;
// Дата зачисления в университет
private int course; // Номер курса
public Student(){} // Конструктор по умолчанию
public Student(String n) { name = n;} // Конструктор 1
public Student(String n, int aCourse, int year, int month,
int day) // Конструктор 2
{ name = n;
course = aCourse;
GregorianCalendar calendar = new GregorianCalendar(year,
month - 1, day);
mDay = calendar.getTime();
}
public void getStudent() // Вывод сведений о студенте
{ System.out.println(name + "; Курс " + course +
"; Дата зачисления: " + mDay);
}
Слайд 17 Конструкторы
public static void main(String[] args)
{ Student
Stud1 = new Student("Сидоров И.П.", 2, 2005, 8,26);
Student
Stud2 = new Student("Петров И.К.");
Student Stud3 = new Student();
Stud1.getStudent();
Stud2.getStudent();
Stud3.getStudent();
}
}
Слайд 18 Конструкторы
Конструктор – это метод класса, который используется для инициализации
нового объекта после его создания. Имя конструктора всегда совпадает с
именем класса, в котором он расположен. У конструкторов нет типа возвращаемого значения (даже типа void).
Между конструкторами и другими методами есть существенная разница: конструктор можно вызывать только в сочетании с операцией new (именно эта операция обеспечивает создание в динамической памяти объекта – экземпляра данного класса). Конструктор нельзя применить к существующему объекту, чтобы изменить информацию в его полях.
Явное указание конструктора в классе необязательно. При отсутствии конструктора вызывается конструктор по умолчанию, который инициализирует поля основных типов нулем или false, а поля объектного типа значением null. (Однако пользоваться этим не стоит – если поля инициализируются неявно, программа становится менее понятной.) Между полями и локальными переменными методов есть существенная разница. Локальные переменные всегда должны явно инициализироваться в методе.
К конструктору по умолчанию можно обратиться только в двух случаях – либо в программе вообще отсутствует какой-либо конструктор, либо, при наличии других конструкторов, он должен быть объявлен явно. Если объявлен какой-либо другой конструктор, а конструктор по умолчанию отсутствует, то обращение к конструктору по умолчанию приведет к ошибке.
В классе может быть несколько конструкторов, но в этом случае они должны отличаться списком или типами параметров.
Еще раз подчеркнем:
Имя конструктора совпадает с именем класса.
Класс может иметь несколько конструкторов.
Конструктор может иметь один или несколько параметров либо не иметь их вообще.
Конструктор ничего не возвращает.
Конструктор всегда вызывается оператором new.
Слайд 19 Конструкторы
В большинстве объектно-ориентированных языков есть явные деструкторы для уничтожения
объектов, которые больше не нужны. В основном, деструкторы освобождают память,
занятую объектами. Поскольку в языке Java есть механизм автоматической сборки мусора, освобождать память вручную нет необходимости, поэтому в языке Java деструкторов нет.
Если объекты используют не только память, но и другие ресурсы, например файлы, или обрабатывают другие объекты, которые, в свою очередь, обращаются к системным ресурсам, то необходимо позаботится об их освобождении в коде метода, работающего с этими ресурсами.
Кроме того, в любой класс можно добавить метод finalize, в котором можно явно освободить используемые ресурсы. Этот метод будет автоматически вызван перед тем, как сборщик мусора уничтожит объект. Однако не следует полагаться на метод finalize, если необходимо возобновить ресурсы и использовать их повторно – момент вызова метода finalize заранее неизвестен.
Возможность объявления нескольких методов (в том числе и конструкторов) с одинаковым именем в одном классе называется перегрузкой метода (method overloading). Перегружаемые методы должны отличаться списком параметров или их типами.
Слайд 20 Конструкторы
Пример 2:
class Dog
{ int age
= 1; // возраст
String name; // кличка
public Dog(){};
public Dog(String n, int a) { name = n; age = a; }
public void voice()
{ for (int i = 1; i <= age; i++)
System.out.println("гав-гав");
System.out.println();
}
}
class NewDog2
{ public static void main (String args [])
{ Dog x = new Dog();
x.voice();
Dog dog1 = new Dog("Тузик", 2);
dog1.voice();
}
}
Слайд 21 Конструкторы
Ключевое слово this в конструкторах:
private int course;
// Метод увеличивает номер курса
public void setCourse(int
i) // Явный параметр i и
// неявный this
{
course += i;
}
// Метод можно переписать и так:
public void setCourse(int i)
{
this.course += i;
}
Слайд 22 Конструкторы
В каждом методе помимо явных параметров присутствует и неявный
параметр, который ссылается на объект, которому принадлежит данный метод. На
этот неявный параметр ссылается ключевое слово this.
В примере явно указывается, что увеличивается именно поле course, а не некая локальная переменная метода. Использование ключевого слово this позволяет легко разделить поля экземпляра и локальные переменные, если возникнет такая необходимость.
В конструкторах у ключевого слова this есть еще одно назначение.
Слайд 23 Конструкторы
Ключевое слово this в конструкторах:
private String
name;
private int course;
private int id = 1;
public Student() {} // Конструктор по умолчанию
public Student(int i) // Конструктор 1
{ this("Студент №" + id, i); // Вызов конструктора 2
id++;
}
public Student(String n, int i) // Конструктор 2
{ name = n;
course = i;
}
…
Student Sidorov = new Student(3);
Слайд 24 Конструкторы
Если первый оператор конструктора имеет вид this(...), то вызывается
другой конструктор этого же класса.
При вызове оператора Student Sidorov
= new Student(3); первый конструктор (конструктор 1) Student(int) вызывает второй конструктор (конструктор 2) Student(String, int).
В языке Си++ невозможно вызвать один конструктор с помощью другого. Для того чтобы разработать общий код инициализации объекта в языке Си++, нужно создавать отдельный метод.
Слайд 25 Статические поля и методы
Статические поля
public class Student
{
private String name;
private
int course;
private static int id = 1;
}
…
Student.id = 5;
public class Math
{
public static final double PI = 3.14159265358979323846;
}
Слайд 26 Статические поля и методы
Поле, имеющее модификатор static, существует в
одном экземпляре. Если же поле не является статическим, то каждый
объект имеет его копию.
Например, допустим, что нам требуется присвоить уникальный идентификационный номер каждому студенту. Добавим в класс Student статическое поле id.
Теперь каждый объект класса Student имеет копии полей name и course. А статическое поле id существует в единственном экземпляре и доступно всем экземплярам класса Student (только им, поскольку поле объявлено как private). Даже если объектов класса Student нет вообще, статическое поле id существует. Оно принадлежит классу, а не конкретному объекту. Чтобы обратиться к этому полю нужно указать имя класса (а не объекта).
Если какой-либо объект класса Student модифицирует значение статического поля, то новое значение получат и другие объекты класса Student.
Статические переменные используются довольно редко. В то же время статические константы используются гораздо чаще. Например, класс Math (вычисление различных математических функций) имеет статическую константу PI.
Обратиться к этой константе в программе можно с помощью выражения Math.PI. Если бы ключевое слово static было пропущено, константа PI была бы обычным константным полем экземпляра класса Math. Это значит, что для доступа к такой константе нужно было бы создать объект класса Math, причем каждый подобной объект имел бы свою копию константы PI.
Как уже упоминалось выше, применять открытые поля не следует никогда, поскольку любой сможет изменить их значения без использования методов объекта. Однако открытые константы (т. е. поля, объявленные с ключевым словом final) можно и нужно использовать.
Слайд 27 Статические поля и методы
Статические методы
double x;
double y;
x = Math.pow(x, y);
…
private static int id = 1;
public static int getId()
{
return id; // Возвращает статическое поле id
}
…
int n = Student.getId(); // Возов статического метода
Слайд 28 Статические поля и методы
Для работы со статическими методами не
нужно создавать объектов. Например, метод pow из класса Math –
статический. Этот метод не использует ни одного объекта класса Math. Другими словами, он не имеет неявного параметра. Следовательно, статические методы – это методы, не имеющие параметра this.
В принципе, можно создать объект и вызать его статический метод, однако это не дает никаких преимуществ, поскольку статический метод все равно не может получить доступ к нестатическим полям объекта. Статические методы имеют доступ только к статическим полям.
Чтобы вызвать этот метод, нужно указать имя класса.
Хотя для вызова статического метода можно использовать и объекты, тем не менее, в этом случае рекомендуется использовать только имя класса, а не объекта.
Статические методы следует применять в двух ситуациях:
Когда методу не нужен доступ к состоянию объекта, поскольку все необходимые параметры задаются явно (например, в методе Math.pow);
Когда методу нужен доступ лишь к статическим полям класса (например, метод Student.getId).
Термин "статический" – исторический курьез. Сначала ключевое слово static было введено в языке Си для обозначения локальных переменных, которые не уничтожались при выходе из блока. В этом контексте слово "статический" имеет смысл: переменная продолжает существовать после выхода из блока, а также при повторном входе в него.
Затем слово "статический" в языке Си приобрело второе значение – глобальные переменные и функции, к которым нельзя получить доступ из других файлов. Ключевое слово static было просто использовано повторно, чтобы не вводить новое.
В языке Си++ это ключевое слово было использовано в третий раз, получив совершенно новую интерпретацию, для обозначения переменных и функций, принадлежащих классу, но не принадлежащих ни одному объекту этого класса. Именно это значение ключевое слово static имеет и в языке Java.
Слайд 29 Блоки инициализации
Пример:
private int id;
private static int nextId;
// Блок
инициализации объекта
{
id = nextId;
nextId++;
}
Способы инициализации статического поля:
static int nextId = 1;
// Статический блок инициализации.
static
{
Random generator = new Random();
nextId = generator.nextInt(10000) ;
}
Слайд 30 Блоки инициализации
Для Ранее были описаны два способа инициализации поля:
Задать
его значение в конструкторе.
Присвоить значение в объявлении.
В языке Java
существует и третий механизм, который называется блоком инициализации (initialization block). Эти блоки выполняются каждый раз, когда создается объект данного класса.
В примере начальное значение поля id задается в блоке инициализации объекта, причем неважно, какой именно конструктор используется для создания объекта. Блок инициализации выполняется первым, а тело конструктора – после него. Этот механизм является совершенно необязательным и обычно не используется. В основном применяются более ясные способы задания начальных значений полей внутри конструктора.
Рассмотрим, что происходит при вызове конструктора.
Все поля данных инициализируются своими значениями, предусмотренными по умолчанию (0, false или null).
Инициализаторы всех полей, и блоки инициализации выполняются в порядке их перечисления в объявлении класса.
Если в первой строке конструктора вызывается другой конструктор, то выполняется вызванный конструктор.
Выполняется тело конструктора.
Инициализировать статическое поле следует либо задав начальное значение, либо используя статический блок инициализации (если для инициализации статических полей класса нужен сложный код).
Слайд 31 Блоки инициализации
Пример:
public class Hello
{
static
{
System.out.println("Привет, мир!");
}
}
Слайд 32 Блоки инициализации
Статическая инициализация выполняется, когда класс загружается впервые. Аналогично
полям экземпляра статические поля принимают значения 0, false или null,
если не заданы другие значения явным образом. Все операторы, задающие начальные значения статических полей, и статические блоки инициализации выполняются в порядке их перечисления в объявлении класса.
Программисты на языке Java часто развлекаются, создавая программу "Привет, мир!", не использующую метода main.
При выполнении команды java Hello класс загружается, статический блок инициализации выводит на печать строку "Привет, мир!", и только затем появляется сообщение о том, что метод main не определен. Этот недостаток можно ликвидировать с помощью вызова метода System.exit(0) в конце статического блока инициализации.
Программа, приведенная ниже, иллюстрирует:
Перегрузку конструкторов.
Вызов другого конструктора с помощью оператора this(...).
Объявление конструктора по умолчанию.
Объявление статических полей и методов.
Объявление блока инициализации объекта.
Объявление статического блока инициализации.
Слайд 33
Пример.
import java.util.*;
public class ConstructorTest
{
public static void
main(String[] args)
{
// Заполняет массив staff
тремя объектами класса Student
Student[] staff = new Student[3];
staff[0] = new Student("Иванов П.И.", 4);
staff[1] = new Student(2);
staff[2] = new Student();
// Выводит на печать информацию о студентах
for (int i = 0; i < staff.length; i++)
{
Student e = staff[i];
System.out.println("имя = " + e.getName()+ ",id = "
+ e.getId()+ ", course = " + e.getCourse());
}
}
}
Слайд 34
class Student
{ private String name = "xxxxxxxxxxx";
// Инициализация поля name
private int course;
private int id;
private static int nextId;
// Блок инициализации объекта
{ id = nextId;
nextId++;
}
// Статический блок инициализации
static
{ Random generator = new Random();
// Задаем nextId как случайное число от 0 до 999
nextId = generator.nextInt(1000);
}
public String getName() {return name;}
public int getCourse() {return course;}
public void setCourse(int course){this.course = course;}
public int getCourse (int course) {return course;}
public int getId(){return id;}
Слайд 35
// Три перегруженных конструктора
public Student(String n, int
i)
{ name = n;
course = i;
}
public Student(int i)
{ // Вызов конструктора Student(String, int)
this("Студент " + nextId, i);
}
// Конструктор по умолчанию
public Student()
{ // Поле name инициализируется значением "xxxxxxxxxxx" -
// см. выше
// Поле course задается неявно - инициализируется нулем
// Поле id задается в блоке инициализации
}
}
Слайд 36 Контрольные вопросы
Понятие класса в Java. Синтаксис
и пример определения класса (без указания модификаторов доступа)
Синтаксис определения
метода класса. Способы передачи параметров в методы.
Понятие объекта в Java. Синтаксис и пример создания объекта. Как организуется доступ к переменным и методам объекта.
Понятие инкапсуляции в ООП. Как реализуется инкапсуляция в Java.
Понятие , назначение и синтаксис конструкторов в Java. Типы конструкторов, примеры использования.
Ссылка this в Java: назначение и варианты явного использования, примеры.
Статические поля и методы: назначение, синтаксис оформления и примеры использования.