Цель лабораторной работы: получить навыки по расширению существующих классов (реализация принципа наследования объектно-ориентированного программирования).
Задание: создать класс путем расширения класса, созданного в предыдущей лабораторной работе. В расширенный класс добавить не менее четырех полей различного типа. Основные результаты работы методов оформить в виде вывода в консоль и в текстовый файл.
Берем за образец предыдущий класс. Наш расширенный тюбик зубной пасты будет дополнен текстовым полем, содержащим путь к текстовому файлу, содержащему историю пользования тюбиком, и файловой переменной, необходимой для создания файла. Напомню, что синтаксис создания класса на основе существующего выглядит следующим образом:
class имя_класса extends имя_суперкласса {
type переменная1_объекта:
type переменная2_объекта:
type переменнаяN_объекта:
type имяметода1(список_параметров) {
тело метода;
}
type имяметода2(список_параметров) {
тело метода;
}
type имя методаМ(список_параметров) {
тело метода;
}
}
Для полноты ощущений будем создавать новый класс в новом файле. Наиболее часто встречающаяся и неочевидная ошибка – это попытка просто расширить класс в его описании. Например, имеем следующий образец кода:
public classParent {
publicParent(String str){
}
}
public classChild extendsParent{
publicChild(String str){
} }
для класса Child происходит ошибка компиляции:
Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor.
То есть, если мы попытаемся создать новый класс следующим образом:
то получим ошибку компиляции. Решение может быть выполнено двумя способами:
1.
public classParent { publicParent(String str){ } } public classChild extendsParent{ publicChild(String str){ super(str); ..... } }
2.
public classParent { publicParent() { } publicParent(String str){ } } public classChild extendsParent{ publicChild(String str){ } }
Таким образом, в нашем случае описание вновь создаваемого класса необходимо дополнить вызовом конструктора суперкласса. Это сделано с помощью ключевого слова super. Обратите внимание, что определять нужно только новые свойства, расширяющие старый класс.
В конструкторе сразу же инициализируем и создадим пустой файл, соответствующий нашему расширенному тюбику. Файловый ввод-вывод осуществляется с помощью конструкции try – catch. Для корректной работы с объектами ввода-вывода нужно в начале описания импортировать стандартный класс ввода-вывода (import java.io.*;). Запись в файл будем производить с помощью объекта BufferedWriter (количество скобок не совпадает, поскольку описание класса не окончено):
import java.io.*;
public class tube_ext extends tube{
File f0;
String filename;
tube_ext(int size, int weight, String name, boolean cap_on, String filename){
super(size, weight, name, cap_on);
this.filename=filename;
try{
File f0 = new File(filename);
// Create file if it does not exist
boolean success = f0.createNewFile();
if (success) {
// File did not exist and was created
} else {
// File already exists
}
} catch (IOException e) {
}
try {
BufferedWriter out = new BufferedWriter(new FileWriter(filename, true));
Далее рекомендована работа по следующему шаблону. Поскольку методы будут отличаться от описанных в классе-предке только записью данных в текстовый файл, то намного проще будет вызывать методы класса-предка с помощью ключевого слова super. Таким образом, каждый метод будет содержать оператор super, а также операции сохранения в текстовый файл значений полей тюбика с необходимыми комментариями. Единственный метод, для которого придется сделать исключение – метод надавливания на тюбик, поскольку мы добавим в него описание «отпускания».
В результате выполнения методов в консоли Eclipse получаем следующее содержимое:
New tube zhemchug with size of 70 and weight of 120
You opened the tube zhemchug, cap_on=false
You pressed the tube zhemchug, weight=110, size=50
You released the tube zhemchug, weight=110, size=70
You closed the tube zhemchug, cap_on=true
Tube zhemchug, weight=110, size=70
Параллельно должен был создаться текстовый файл zhemchug.txt, в котором записаны результаты выполнения методов. Если не задавать пути, то он находится в папке, соответствующей проекту в папке рабочей области (workspace). Его содержимое:
Y o u ' v e c l o s e d t h e t u b e z h e m c h u g , c a p _ o n = t r u e s i z e = 7 0 w e i g h t = 1 1 0
Методы классов BufferedWriter и RandomAccessFile для записи в текстовый файл отличаются по своему исполнению, поэтому текстовые данные, полученные в результате методов открытия/нажатия и закрытия тюбика, могут отличаться.
Таким образом, мы создали новый класс на основе существующего. Основное отличие – запись данных полей, которые изменяются в процессе выполнения методов, в текстовый файл.
Рассмотрим еще один пример класса с расширением. Это будет описание прямоугольника. Поля (свойства) класса: стороны. Методы класса – вычисление периметра, площади и диагонали. Текст программы, описывающей класс:
public class rectangle {
int a, b;
rectangle(int a, int b){
this.a=a;
this.b=b;
}
void square (int a, int b){
int square=a*b;
System.out.println("Площадь равна "+square);
}
void perimeter(int a, int b){
int perimeter=(a+b)*2;
System.out.println("Периметр равен "+perimeter);
}
void diag (int a, int b){
double diag=Math.sqrt(a*a+b*b);
System.out.println("Диагональ равна "+diag);
}
}
Теперь расширим класс прямоугольника до прямоугольного параллелепипеда. Очевидно, что в новом классе добавится поле высоты. Методы расширенного класса будут рассчитывать диагональ уже объемного параллелепипеда и его объем:
public class parall extends rectangle{
int h;
parall(int a, int b, int h){
super(a,b);
this.h=h;
}
void diag(int a, int b, int h){
double diag=Math.sqrt(a*a+b*b+h*h);
System.out.println("Диагональ параллелепипеда равна "+diag);