JAVA_Лаб_раб_5. Лабораторная работа 5. Наследование. Переопределение методов. Класс Object. Цель работы
Скачать 0.72 Mb.
|
1 Лабораторная работа №5. Наследование. Переопределение методов. Класс Object. Цель работы: Получить основные понятия по следующим разделам языка Java: наследование, переопределение методов, класс Object. Теоретическая часть Наследование (inheritance) – это отношение между классами, при котором класс использует структуру или поведение другого (одиночное наследование) или других (множественное наследование) классов. Наследование вводит иерархию "общее/частное", в которой подкласс наследует от одного или нескольких более общих суперклассов. Подклассы обычно дополняют или переопределяют унаследованную структуру и поведение. Расширим класс Employee следующим образом. Необходимо описать класс, экземпляры которого представляли бы менеджера предприятия. Менеджер является таким же сотрудником, однако у него есть дополнительное поле – премия. Соответственно, метод, который возвращал в классе сотрудник Employee размер заработной платы, больше не подходит для менеджера. Теперь каждый экземпляр класса Manager имеет 4 поля – name, salary, hiredate, bonus. Определяя подкласс, нужно указать лишь отличия между подклассом (потомком) и суперклассом (родителем). Разрабатывая классы, следует помещать методы общего назначения в суперкласс, а более специальные – в подкласс. В приведенном выше примере не все методы родительского класса Employee подходят для класса Manager. В частности, метод getSalary() 2 должен возвращать сумму базовой зарплаты и премии. Следовательно, нужно реализовать новый метод, переопределяющий (overriding) метод класса родителя. Сделать это можно следующим образом: class Manager extends Employee{ … // переопределение (замещение) метода класса родителя @Override public void getSalary() { double basesalary=super.getSalary(); return basesalary+bonus; } } Метод getSalary класса Manager как бы замещает метод класса Employee. Наследование позволяет создавать иерархии классов. Иерархия представляется в виде дерева, в котором более общие объекты располагаются ближе к корню, а более специализированные — на ветвях и листьях. Наследование облегчает использование библиотек объектов, поскольку программист может взять за основу объекты из библиотеки и создать их наследников с требуемыми свойствами. В Java любой класс может иметь одного предка и произвольное количество потомков. Пример иерархии классов показан на следующем рисунке: Если в иерархии классов имя и сигнатура типа метода подкласса совпадает с атрибутами метода суперкласса, то метод подкласса переопределяет метод суперкласса. Когда переопределённый метод вызывается из своего подкласса, он всегда будет ссылаться на версию этого метода, определённую подклассом. А версия метода из суперкласса будет скрыта. 3 Если нужно получить доступ к версии переопределённого метода, определённого в суперклассе, то используется ключевое слово super. Важно не путать переопределение с перегрузкой. Переопределение метода выполняется только в том случае, если имена и сигнатуры типов двух методов идентичны. В противном случае два метода являются просто перегруженными. В Java SE5 появилась запись @Override. Она не является ключевым словом, однако при использовании @Override компилятор выдаст сообщение об ошибке, если вместо переопределения будет случайно выполнена перегрузка. Класс Object На вершине иерархии классов Java находится класс Object, который является суперклассом для всех классов. Ссылочная переменная типа Object может указывать на объект любого другого класса, на любой массив, так как массивы реализуются как классы. В классе Object определен набор методов, который наследуется всеми классами: protected Object clone() – создает и возвращает копию вызывающего объекта; boolean equals(Object ob) –предназначен для переопределения в подклассах с выполнением общих соглашений о сравнении содержимого двух объектов; Class extends Object> getClass() –возвращает объект типа Class; protected void finalize() –вызывается перед уничтожением объекта автоматическим сборщиком мусора (garbage collection); int hashCode() –возвращает хэш-код объекта; String toString() –возвращает представление объекта в виде строки. Методы notify(), notifyAll() и wait() будут рассмотрены в главе «Потоки выполнения». Если при создании класса предполагается проверка логической эквивалентности объектов, которая не выполнена в суперклассе, следует переопределить два метода: equals(Object ob) и hashCode(). Кроме того, переопределение этих методов необходимо, если логика приложения предусматривает использование элементов в коллекциях. Метод equals() при сравнении двух объектов возвращает истину, если содержимое объектов эквивалентно, и ложь – в противном случае. При переопределении метода 4 equals() должны выполняться соглашения, предусмотренные спецификацией языка Java, а именно: рефлексивность – объект равен самому себе; симметричность – если x.equals(y) возвращает значение true , то и y.equals(x) всегда возвращает значение true; транзитивность – если метод equals() возвращает значение true при сравнении объектов x и y, а также y и z, то и при сравнении x и z будет возвращено значение true; непротиворечивость – при многократном вызове метода для двух не подвергшихся изменению за это время объектов возвращаемое значение всегда должно быть одинаковым; ненулевая ссылка при сравнении с литералом null всегда возвращает значение false. При создании информационных классов также рекомендуется переопределять методы hashCode() и toString(), чтобы адаптировать их действия для создаваемого типа. Метод hashCode() переопределен, как правило, в каждом классе и возвращает число, являющееся уникальным идентификатором объекта, зависящим в большинстве случаев только от значения объекта. Его следует переопределять всегда, когда переопределен метод equals(). Метод hashCode() возвращает хэш-код объекта, вычисление которого управляется следующими соглашениями: во время работы приложения значение хэш-кода объекта не изменяется, если объект не был изменен; все одинаковые по содержанию объекты одного типа должны иметь одинаковые хэш-коды; различные по содержанию объекты одного типа могут иметь различные хэш-коды. Один из способов создания правильного метода hashCode(), гарантирующий выполнение соглашений, приведен ниже, в примере # 10. Метод toString() следует переопределять таким образом, чтобы кроме стандартной информации о пакете (опционально), в котором находится класс, и самого имени класса (опционально), он возвращал значения полей объекта, вызвавшего этот метод (то есть всю полезную информацию объекта), вместо хэш-кода, как это делается в классе Object. Метод toString() класса Object возвращает строку с описанием объекта в виде: getClass().getName() + '@' + Integer.toHexString(hashCode()) 5 Метод вызывается автоматически, когда объект выводится методами println(), print() и некоторыми другими. // Пример: переопределение методов equals(), hashCode, toString(): public class Student { private int id; private String name; private int age; public Student(int id, String name, int age){ this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (obj instanceof Student){ //warning Student temp = (Student) obj; return this.id == temp.id && name.equals(temp.name) && this.age == temp.age; } else return false; } public int hashCode() { return (int)(31 * id + age + ((name == null) ? 0 : name.hashCode())); } public String toString() { return getClass().getName()+"@name" +name + " id:" + id + " age:" + age; } } Выражение 31 * id + age гарантирует различные результаты вычислений при перемене местами значений полей, а именно если id=1 и age=2 , то в результате будет получено 33, если значения поменять 6 местами, то 63. Такой подход применяется при наличии у классов полей базовых типов. Метод equals() переопределяется для класса Student таким образом, чтобы убедиться в том, что полученный объект является объектом типа Student или одним из его наследников, а также сравнить содержимое полей id, name и age соответственно у вызывающего метод объекта и объекта, передаваемого в качестве параметра. Рекомендации по проектированию классов Всегда храните данные в переменных, объявленных как private Всегда инициализируйте данные Не используйте в классе слишком много простых типов Не для всех полей надо создавать методы доступа и модификации Используйте стандартную форму определения класса Разбивайте на части слишком большие классы Выбирайте для классов и методов осмысленные имена Общая постановка задачи 1. Изучить предлагаемый теоретический материал, а также лекционный материал по данной теме. 2. Разработать класс, описанный в Вашем варианте задания. Класс должен содержать следующие элементы: скрытые поля, конструкторы с параметрами и без параметров, методы. Функциональные элементы класса должны обеспечивать непротиворечивый, полный, минимальный и удобный интерфейс класса. При возникновении ошибок должны выбрасываться исключения. 3. В разрабатываемом классе должны быть переопределены следующие методы класса Object: o boolean equals(Object ob) – предназначен для сравнении содержимого двух объектов; o int hashCode() – возвращает хэш-код объекта; o String toString() – возвращает представление объекта в виде строки. 4. Для разработанного класса создать класс-наследник или же создать базовый абстрактный класс, для которого разработанный класс будет наследником. 5. В программе должна выполняться проверка всех разработанных классов. Для проверки необходимо создать отдельный класс с методом main. 6. Набрать программу и отладить её работу в среде NetBeans IDE. 7. Подобрать тестовые данные. Протестировать. 8. Оформить отчет по лабораторной работе, включающий: 7 o титульный лист; o цель работы; o постановку задачи для Вашего варианта; o текст программы на языке Java; o скриншоты результатов выполнения тестовых примеров; o ответы на контрольные вопросы. Список индивидуальных данных Вариант 1. Описать класс, реализующий десятичный счетчик, который может увеличивать или уменьшать свое значение на единицу в заданном диапазоне. Предусмотреть инициализацию счетчика значениями по умолчанию и произвольными значениями. Счетчик имеет методы увеличения и уменьшения, а также метод, позволяющий получить его текущее состояние. При выходе за границы диапазона выбрасываются исключения. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 2. Описать класс, реализующий шестнадцатеричный счетчик, который может увеличивать или уменьшать свое значение на единицу в заданном диапазоне. Предусмотреть инициализацию счетчика значениями по умолчанию и произвольными значениями. Счетчик имеет методы увеличения и уменьшения, а также метод, позволяющий получить его текущее состояние. При выходе за границы диапазона выбрасываются исключения. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 3. Описать класс, представляющий треугольник. Предусмотреть методы для создания объектов, перемещения на плоскости, изменения размеров и вращения на заданный угол. Создать методы для получения состояния объекта. При невозможности построения треугольника выбрасывается исключение. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 4. Построить описание класса, содержащего информацию о почтовом адресе организации. Предусмотреть возможность раздельного изменения составных частей адреса и проверки допустимости вводимых значений. В случае недопустимых значений полей выбрасываются исключения. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 5. Составить описание класса для представления комплексных чисел. Обеспечить выполнение операций сложения, вычитания и умножения комплексных чисел. Написать программу, демонстрирующую все разработанные элементы класса. 8 Вариант 6. Составить описание класса для вектора, заданного координатами его концов в трехмерном пространстве. Обеспечить операции сложения и вычитания векторов с получением нового вектора (суммы или разности), вычисления скалярного произведения двух векторов, длины вектора, косинуса угла между векторами. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 7. Составить описание класса прямоугольников со сторонами, параллельными осям координат. Предусмотреть возможность перемещения прямоугольников на плоскости, изменение размеров, построение наименьшего прямоугольника, содержащего два заданных прямоугольника, и прямоугольника, являющегося общей частью (пересечением) двух прямоугольников. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 8. Составить описание класса для представления даты. Предусмотреть возможности установки даты и изменения ее отдельных полей (год, месяц, день) с проверкой допустимости вводимых значений. В случае недопустимых значений полей выбрасываются исключения. Создать методы изменения даты на заданное количество дней, месяцев и лет. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 9. Составить описание класса для представления времени. Предусмотреть возможности установки времени и изменения его отдельных полей (час, минута, секунда) с проверкой допустимости вводимых значений. В случае недопустимых значений полей выбрасываются исключения. Создать методы изменения времени на заданное количество часов, минут и секунд. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 10. Составить описание класса многочлена вида ах 2 + bх + с. Предусмотреть методы, реализующие: • вычисление значения многочлена для заданного аргумента; • операцию сложения, вычитания и умножения многочленов с получением нового объекта-многочлена; • вывод на экран описания многочлена. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 11. Описать класс, представляющий треугольник. Предусмотреть методы для создания объектов, вычисления площади, периметра и точки пересечения медиан. Создать методы для получения состояния объекта. При невозможности построения треугольника выбрасывается исключение. Написать программу, демонстрирующую все разработанные элементы класса. 9 Вариант 12. Описать класс, представляющий круг. Предусмотреть методы для создания объектов, вычисления площади круга, длины окружности и проверки попадания заданной точки внутрь круга. Создать методы для получения состояния объекта. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 13. Описать класс для работы со строкой, позволяющей хранить только двоичное число и выполнять с ним арифметические операции. Предусмотреть инициализацию с проверкой допустимости значений. В случае недопустимых значений выбрасываются исключения. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 14. Описать класс дробей - рациональных чисел, являющихся отношением двух целых чисел. Предусмотреть методы сложения, вычитания, умножения и деления дробей. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 15. Описать класс «цветная линия», содержащий координаты линии и её цвет. Цвет описывается с помощью трех составляющих (красный, зеленый, синий). Предусмотреть различные методы инициализации объекта с проверкой допустимости значений. Допустимым диапазоном для каждой составляющей является [0, 255]. Описать методы добавления информации в конец файла и для получения состояния файла. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 16. Описать класс «комната», содержащий сведения о метраже, высоте потолков и количестве окон. Предусмотреть инициализацию с проверкой допустимости значений полей. В случае недопустимых значений полей выбрасываются исключения. Описать методы вычисления площади и объема комнаты и для получения состояния объекта. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 17. Описать класс, представляющий нелинейное уравнение вида ах - cos(x) = 0. Описать метод, вычисляющий решение этого уравнения на заданном интервале методом деления пополам и выбрасывающий исключение в случае отсутствия корня. Создать методы для получения состояния объекта. Написать программу, демонстрирующую все разработанные элементы класса. Вариант 18. Описать класс, представляющий квадратное уравнение вида ах 2 + bх + с = 0. Описать метод, вычисляющий решение этого уравнения и выбрасывающий исключение в случае отсутствия корней. Создать методы для получения состояния объекта. Написать программу, демонстрирующую все разработанные элементы класса. 10 Вариант 19. Описать класс «процессор», содержащий сведения о марке, тактовой частоте, объеме кэша и стоимости. Предусмотреть инициализацию с проверкой допустимости значений полей. В случае недопустимых значений полей выбрасываются исключения. Создать методы для получения состояния объекта. Описать класс «материнская плата», включающий класс «процессор» и объем установленной оперативной памяти. Предусмотреть инициализацию с проверкой допустимости значений поля объема памяти. В случае недопустимых значений поля выбрасывается исключение. Создать методы для получения состояния объекта. Написать программу, демонстрирующую все разработанные элементы классов. Вариант 20. Описать класс «цветная точка». Для точки задаются координаты и цвет. Цвет описывается с помощью трех составляющих (красный, зеленый, синий). Предусмотреть различные методы инициализации объекта с проверкой допустимости значений. Допустимым диапазоном для каждой составляющей является [0, 255]. В случае недопустимых значений полей выбрасываются исключения. Создать методы для получения состояния объекта и метод изменения цвета. Написать программу, демонстрирующую все разработанные элементы класса. Контрольные вопросы к защите 1. Дайте определение класса. 2. Что такое объект и в чем его отличие от класса? 3. Как методы доступа к отдельным элементам класса существуют? 4. Для чего используется конструктор? 5. Что такое метод класса? 6. Перечислите набор методов определенных в классе Object. Библиографический список 1. Информационные материалы с официального сайта разработчиков. [электронный ресурс] http://www.oracle.com/technetwork/java/javase/downloads/index.html 2. Вязовик, Н.А. Программирование на Java. [электронный ресурс] http://www.intuit.ru/studies/courses/16/16/info 3. Монахов В.В. Язык программирования Java и среда NetBeans: [электронный ресурс] http://www.intuit.ru/studies/courses/569/425/info 4. Хорстманн К.С., Корнелл Г. Библиотека профессионала. JAVA 2. Том 1. Основы. 8-е издание. Пер. с англ. – М.: ООО Издательский дом “Вильямс”, 2008. – 816 с. 5. Эккель Б. Философия JAVA. 4-е издание. – СПб.: Питер, 2009. – 638с. 11 Пример выполнения работы Файл Quadratic.php package labwork5; /** * Описать класс, представляющий квадратное уравнение вида ах 2 + bх + с = 0. Описать метод, вычисляющий решение этого уравнения и выбрасывающий исключение в случае отсутствия корней. Создать методы для получения состояния объекта. Написать программу, демонстрирующую все разработанные элементы класса. * @author Admin */ public class Quadratic { protected int a ; protected int b ; protected int c ; protected int d ; protected int x1 ; protected int x2 ; // public Quadratic( int a, int b, int c) { setA(a); setB(b); setC(c); } // public int getA() { return a ; } public int getB() { return b ; } public int getC() { 12 return c ; } public int getD() { return d ; } public int getX1() { return x1 ; } public int getX2() { return x2 ; } // public void setA( int newa) { if (newa >= - 1000 && newa <= 1000 ) a = newa; else throw new IllegalArgumentException( "ОШИБКА! Коэффициент А должен быть в диапазоне [-1000..1000]" ); } public void setB( int newb) { if (newb > 0 ) b = newb; else throw new IllegalArgumentException( "ОШИБКА! Коэффициент B должен быть положительным." ); } public void setC( int newc) { c = newc; } // @Override public boolean equals(Object obj) { if ( this == obj) { return true ; } 13 if (obj == null ) { return false ; } if (obj instanceof Quadratic) { Quadratic temp = (Quadratic) obj; return this a == temp. a && this b == temp. b && this c == temp. c ; } else { return false ; } } // @Override public int hashCode() { int hash = 10 ; hash = 31 * hash + this a ; hash = 31 * hash + this b ; hash = 31 * hash + this c ; return hash; } // @Override public String toString() { String str = "A = " + a + "; B = " + b + "; C = " + c + "; X1 = " + x1 ; if ( d == 0 ) { str += "; Diskriminant = " + d ; } else if ( d > 0 ) { str += "; X2 = " + x2 ; str += "; Diskriminant " + d ; } return str; } 14 /** * Вычисление дискриминанта */ public void Diskriminant() { d = ( b * b ) - ( 4 * a * c ); if ( d < 0 ) { throw new NullPointerException( "ОШИБКА! Дискриминант меньше нуля. Решения нет." ); } else if ( d == 0 ) { x1 = ( int ) ((- b - Math.sqrt( d )) / ( 2 * a )); } else if ( d > 0 ) { x1 = ( int ) ((- b - Math.sqrt( d )) / ( 2 * a )); x2 = ( int ) ((- b + Math.sqrt( d )) / ( 2 * a )); } } } 15 Файл Main.php package labwork5; import java.util.Scanner; public class Main { public static void main(String[] args) { int a, b, c; Scanner scan = new Scanner(System. in ); System. out .print( "A = " ); a = scan.nextInt(); System. out .print( "B = " ); b = scan.nextInt(); System. out .print( "C = " ); c = scan.nextInt(); try { Quadratic q1 = new Quadratic(a, b, c); q1.Diskriminant(); System. out .println(q1); } catch (IllegalArgumentException e) { System. out .println(e.getMessage()); } catch (NullPointerException e) { System. out .println(e.getMessage()); } } } |