Основной целью выполнения лабораторной работы является получение навыков по созданию собственных классов и работе с экземплярами классов.
Задание: создать собственный класс. В качестве примера взять класс, выбранный в контрольной работе №1. Класс должен содержать не менее пяти полей (свойств) различного типа: целочисленного, дробного, текстового. Также описание класса должно содержать не менее пяти методов и конструктор класса. Два метода из пяти должны возвращать значения. Основные результаты работы методов оформить в виде вывода в консоль.
В качестве примера рассмотрим создание абстрактного класса. Например, пусть это будет тюбик зубной пасты. Согласно [1], синтаксис описания класса следующий:
class имя_класса extends имя_суперкласса {
type переменная1_объекта:
type переменная2_объекта:
type переменнаяN_объекта:
type имяметода1(список_параметров) {
тело метода;
}
type имяметода2(список_параметров) {
тело метода;
}
type имя методаМ(список_параметров) {
тело метода;
}
}
В нашем примере создается класс, описывающий тюбик со следующими параметрами: целочисленными размером и объемом (int size, weight;), логическим индикатором крышки (boolean cap_on; true – закрыт, false - открыт), строковым названием (String name;):
public class tube {
int size, weight;
boolean cap_on;
String name;
Далее следует описать конструктор класса, вызываемый при создании нового экземпляра класса tube. В нашем случае в конструкторе всем полям буду присваиваться значения, соответствующие значению аргументов, переданных в метод-конструктор. Кроме того, в консоль будет выведена информация о вновь созданном объекте – тюбике. Имя конструктора должно совпадать с именем класса:
tube(int size, int weight, String name, boolean cap_on){
this.size=size;
this.weight=weight;
this.name=name;
this.cap_on=true;
System.out.println("New tube "+this.name+" with size of "+this.size+" and weight of "+this.weight);
}
Оператор «+», используемый в инструкции System.out.println, реализует операцию конкатенации, т.е. склейки текстовых выражений. В отличие от других сред (например, Delphi), Java автоматически приводит различные типы данных к текстовому, поэтому конвертирование не нужно.
Методы нашего класса будут очень простыми: в них будут меняться значения свойств. Поскольку нам нужно как-то контролировать результат работы методов, то каждый метод будет выводить результаты свойств в консоль. В качестве параметров будем использовать изменяемые и выводимые значения свойств (хотя это не всегда обязательно). Создаем метод tube_open, соответствующий открытию тюбика (снятие крышки):
public void tube_open(String name, boolean cap_on)
{
this.cap_on=false;
System.out.println("You opened the tube " + name +", cap_on="+this.cap_on);
}
Далее описываем сжатие тюбика. Обратите внимание, что значение свойства weight (объем) будет последовательно меняться всякий раз при вызове метода tube_pressed. Полагаем, что мы, в конце концов, можем израсходовать тюбик, о чем нужно вывести предупреждение в консоли. Для этого используем характерную особенность языка Java: обращение непосредственно к значению поля с помощью использования ключевого слова this. К полю size в методе обращаемся без ключевого слова this. Это означает, что во время выполнения метода в памяти будет создана копия поля size, содержащая значение. Если в методе изменяется значение поля size, то, соответственно, будет изменено значение этой копии, а не непосредственно поля size. После выполнения метода копия поля size, содержащая измененное значение, будет уничтожена сборщиком мусора, и значение поля size возвратится к первоначальному. Это соответствует логике: мы сжимаем тюбик, чтобы выдавить пасту, а потом он распрямляется:
public void tube_pressed (int weight, int size, String name){
weight-=10;
this.weight=weight;
size-=20;
System.out.println("You pressed the tube "+name+", weight="+weight+", size="+size);
Мы закончили описание шаблона, на основе которого можно создавать экземпляры класса. Обратите внимание, что программа не содержит метода main. Теперь необходимо создать программу, в которой этот вызов будет реализован. Для этого надо создать еще один класс внутри нашего проекта, содержащий метод main. В нем мы будем создавать экземпляр тюбика зубной пасты Colgate. Синтаксис создания нового экземпляра класса следующий:
имя_класса объектная_переменная = new имя_класса (параметры);
После выполнения этой строки будет выполнено обращение к конструктору класса. Параметры в данном случае являются параметрами конструктора.
Числовые значения выбраны произвольно. Обратите внимание, что во время вызова методов класса в них передаются значения свойств конкретного объекта – экземпляра класса.
public class teethpaste_tube {
public static void main(String[] args) {
// TODO Auto-generated method stub
tube colgate= new tube(100, 180, "Colgate", true);
New tube Colgate with size of 100 and weight of 180
You opened the tube Colgate, cap_on=false
You pressed the tube Colgate, weight=170, size=80
You closed the tube Colgate, cap_on=true
Tube Colgate, weight=170, size=100
You opened the tube Colgate, cap_on=false
You pressed the tube Colgate, weight=160, size=80
Рассмотрим еще один пример создания класса по мотивам популярной передачи «Разрушители мифов» - MythBusters. Там рассказывалось о листе бумаги, который невозможно сложить более семи раз подряд вдоль короткой стороны. Попробуем создать класс, описывающий такой лист бумаги. Класс будет иметь следующие поля: длина, ширина, количество складываний, количество слоев. В классе будет один основной метод, описывающий складывание. Еще один побочный метод будет возвращать значение текущей площади листа с учетом складываний. Описание основного класса листа:
public class list {
double length, width;
int bend_times, layers;
list(double length, double width){
this.layers=1;
this.bend_times=0;
this.length=length;
this.width=width;
}
public void bending(){
if (this.length>this.width)
this.length/=2;
else if (this.length<this.width)
this.width/=2;
this.layers*=2;
this.bend_times++;
System.out.println("Лист а4 сложен "+this.bend_times+" раз, длина "+this.length+" ,ширина "+this.width+" ,слоев "+this.layers+", количество складываний "+this.bend_times);
System.out.println("Площадь листа в текущий момент равна "+square(this.length,this.width));
}
public double square (double x, double y){
return x*y;
}
}
Класс, содержащий метод main:
public class pusk {
public static void main(String[] args) {
list a4=new list(210, 297);
for (int i=1;i<=7;i++)
a4.bending();
} }
Результат, выводимый в консоли:
Лист а4 сложен 1 раз, длина 210.0 ,ширина 148.5 ,слоев 2, количество складываний 1
Площадь листа в текущий момент равна 31185.0
Лист а4 сложен 2 раз, длина 105.0 ,ширина 148.5 ,слоев 4, количество складываний 2
Площадь листа в текущий момент равна 15592.5
Лист а4 сложен 3 раз, длина 105.0 ,ширина 74.25 ,слоев 8, количество складываний 3
Площадь листа в текущий момент равна 7796.25
Лист а4 сложен 4 раз, длина 52.5 ,ширина 74.25 ,слоев 16, количество складываний 4
Площадь листа в текущий момент равна 3898.125
Лист а4 сложен 5 раз, длина 52.5 ,ширина 37.125 ,слоев 32, количество складываний 5
Площадь листа в текущий момент равна 1949.0625
Лист а4 сложен 6 раз, длина 26.25 ,ширина 37.125 ,слоев 64, количество складываний 6
Площадь листа в текущий момент равна 974.53125
Лист а4 сложен 7 раз, длина 26.25 ,ширина 18.5625 ,слоев 128, количество складываний 7
Площадь листа в текущий момент равна 487.265625
Со вторым классом разобраться самостоятельно.
Вопросы к работе:
1. Что такое класс?
2. Что такое свойство?
3. Какого типа может быть свойство?
4. Как описать поле в классе Java?
5. Что такое метод?
6. Что такое конструктор класса? Требования к конструктору в Java.
7. Когда вызывается конструктор?
8. В чем отличие между классом и объектом?
9. Что такое параметр?
10. Как передать параметр в методе?
11. Как создать метод, возвращающий значение?
12. Зачем нужно использование ключевого слова this?
13. Сократите запись a=a-50.
14. Сократите запись с=с+1.
15. Что такое конкатенация?
16. Что означает void?
17. Синтаксис алгоритма ветвления.
18. Синтаксис циклического алгоритма с использованием for.