Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Методы класса

Читайте также:
  1. II. Рыночные методы установления цены на товар
  2. IV. ФОРМЫ И МЕТОДЫ КОНТРОЛЯ, СИСТЕМА ОЦЕНОК
  3. IV. Эконометрические методы определения цен
  4. Абстрактные методы и классы
  5. Активные методы исследования
  6. Анализ имущественного положения организации: цели, источники информации, методы и приемы, показатели оценки структуры баланса.
  7. Анализ источников финансирования: цели, источники информации, методы и приемы, оценка структуры и динамики.
  8. Анатомические особенности сердца и методы его исследования
  9. Анатомо-физиологические особенности и методы исследования крови, эндокринной, пищеварительной и мочевыделительной систем
  10. АНАТОМО-ФИЗИОЛОГИЧЕСКИЕ ОСОБЕННОСТИ И МЕТОДЫ ИССЛЕДОВАНИЯ СИСТЕМЫ ОРГАНОВ ДЫХАНИЯ И КРОВООБРАЩЕНИЯ. НОРМАЛЬНАЯ ЭКГ.

Как мы уже видели, вызов метода экземпляра осуществляется следующим образом:

variableWithInstance.methodName();

Мы вызвали метод именованной переменной, хранящей экземпляр класса. Вызов метода класса осуществляется следующим образом:

ClassName.methodName();

Нам не нужен экземпляр для вызова этого метода. Для этого применяется сам класс. Используемый нами метод main()является методом класса. Взгляните на его сигнатуру. Обратите внимание на то, что он объявлен как public static. Мы видели этот спецификатор доступа прежде. Ключевое слово static указывает, что это метод класса, вот почему такие методы иногда называются статическими методами. Нам не нужен экземпляр Adult для вызова main().

Мы можем создать методы класса для Adult при желании, хотя в действительности нет причины делать это в данном случае. Хотя для демонстрационных целей добавим тривиальный метод класса:

public static void doSomething() { System.out.println("Did something"); }

Закомментируйте имеющиеся строки кода в методе main() и добавьте следующие строки:

Adult.doSomething(); Adult myAdult = new Adult(); myAdult.doSomething();

После выполнения этого кода вы должны увидеть соответствующее сообщение, дважды отображенное на консоли. Первый вызов doSomething() является обычным способом вызова метода класса. Можно также вызвать его через экземпляр класса, как это сделано в третьей строке кода. Но это, в действительности, не очень хорошая практика. Eclipse предупредит об этом, подчеркнув эту строку желтой волнистой линией, и предложит обратиться к этому методу "статическим способом" через класс, а не через экземпляр.

Сравнение объектов с использованием ==

Существует два способа сравнить объекты в языке Java:

· Оператор ==

· Оператор equals()

Первый, наиболее употребляемый, сравнивает объекты на равенство. Другими словами, выражение:

a == b

возвратит true тогда и только тогда, когда a и b ссылаются точно на тот же экземпляр класса (то есть, на тот же объект). Исключение составляют примитивы. При сравнении двух примитивов с использованием оператора == система времени исполнения Java сравнивает их значения (они не являются настоящими объектами). Попробуйте поместить этот код в main() и взгляните на результат, отображаемый в консоли:

int int1 = 1; int int2 = 1; Integer integer1 = new Integer(1); Integer integer2 = new Integer(1); Adult adult1 = new Adult(); Adult adult2 = new Adult();   System.out.println(int1 == int2); System.out.println(integer1 == integer2); integer2 = integer1; System.out.println(integer1 == integer2); System.out.println(adult1 == adult2);

Первое сравнение возвращает true, поскольку сравниваются примитивы с одинаковыми значениями. Второе сравнение возвращает false, поскольку две переменные не ссылаются на один и тот же экземпляр объекта. Третье сравнение возвращает true, потому что две переменные теперь ссылаются на один и тот же экземпляр. Если сделать то же самое с нашим классом, мы тоже получим false, потому что adult1 и adult2 не ссылаются на один и тот же экземпляр.

Сравнение объектов с использованием equals()

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

a.equals(b);

Метод equals() принадлежит типу Object, который является предком каждого класса в языке Java. Это означает, что любой созданный вами класс будет наследовать базовое поведение equals() от Object. Это базовое поведение не отличается от оператора ==. Другими словами, по умолчанию эти два выражения используют оператор == и возвращают значение false:

a == b; a.equals(b);

Посмотрите на метод spendMoney() класса Adult снова. Что происходит за кулисами, когда мы вызываем метод contains()нашей переменной wallet? Язык Java использует оператор == для сравнения объектов в списке с указанным объектом. Если он находит соответствие, метод возвращает значение true; в противном случае возвращается false. Поскольку мы сравниваем примитивы, он может найти соответствие, основанное на целочисленных значениях (помните, что оператор == сравнивает примитивы по их значению).

Это хорошо для примитивов, но что если мы хотим сравнить содержимое объектов? Оператор == не сделает это. Для сравнения содержимого объектов мы должны перегрузить метод equals() класса, экземпляром которого является переменная a. Это означает, что нужно создать метод с точно такой же сигнатурой, что и у метода одного из ваших суперклассов, но реализовать метод по другому. Если сделать это, вы сможете сравнивать содержимое двух объектов, а не только проверять, ссылаются ли две переменные на один и тот же экземпляр.

Попробуйте ввести следующий код в метод main() и взгляните на результат, отображаемый в консоли:

Adult adult1 = new Adult(); Adult adult2 = new Adult();   System.out.println(adult1 == adult2); System.out.println(adult1.equals(adult2));   Integer integer1 = new Integer(1); Integer integer2 = new Integer(1);   System.out.println(integer1 == integer2); System.out.println(integer1.equals(integer2));

Первое сравнение возвращает значение false, поскольку adult1 и adult2 ссылаются на разные экземпляры Adult. Второе сравнение тоже возвращает значение false, поскольку реализация метода equals() по умолчанию просто проверяет, ссылаются ли обе переменные на один и тот же экземпляр. Но поведение equals() по умолчанию обычно не то, что мы хотим. Мы хотели бы сравнивать содержимое двух объектов Adult, чтобы узнать, одинаковые ли они. Для этого мы можем перегрузить equals(). Как видно из двух последних сравнений в приведенном выше примере, классInteger перегружает метод так, что оператор == возвращает false, но оператор equals() сравнивает на равенство упакованные значения int. Мы сделаем что-то похожее для класса Adult в следующем разделе.

Перегрузка equals()

Перегрузка метода equals() для сравнения объектов на самом деле требует от нас перегрузки двух методов:

public boolean equals(Object other) { if (this == other) return true;   if (!(other instanceof Adult)) return false;   Adult otherAdult = (Adult)other; if (this.getAge() == otherAdult.getAge() && this.getName().equals(otherAdult.getName()) && this.getRace().equals(otherAdult.getRace()) && this.getGender().equals(otherAdult.getGender()) && this.getProgress() == otherAdult.getProgress() && this.getWallet().equals(otherAdult.getWallet())) return true; else return false; }   public int hashCode() { return firstname.hashCode() + lastname.hashCode(); }

Мы перегрузим метод equals() следующим способом, который является обычным стилем в Java:

· Если объект, который мы собираемся сравнивать, является самим этим объектом, то они очевидно равны, поэтому возвращаем true.

· Проверяем для уверенности, что объект, который мы собираемся сравнивать, является экземпляром Adult (если нет, два объекта очевидно не одинаковы).

· Приводим тип входного объекта к Adult, для того чтобы использовать его методы.

· Сравниваем части двух объектов Adult, которые должны быть равны, для того чтобы два объекта считались "равными" (какое бы определение равенства мы ни использовали).

· Если какие-либо из этих частей не равны, возвращаем значение false; в противном случае возвращаем true.

Обратите внимание на то, что мы можем сравнить возраст каждого объекта с помощью ==, поскольку это примитивные значения. Для сравнения String мы используем equals(), поскольку этот класс перегружает метод equals() для сравнения содержимого объектов String (если бы мы использовали ==, то получали бы false каждый раз, потому что два объекта String никогда не будут одним и тем же объектом). То же самое мы делаем и для ArrayList, поскольку он перегружает equals() для проверки того, что два списка содержат одинаковые элементы в одинаковом порядке. Это хорошо подходит для нашего простого примера.

Когда бы вы ни перегрузили equals(), необходимо также перегрузить hashCode(). Объяснение причины этого выходит за рамки данного руководства, а пока просто знайте, что язык Java использует значение, возвращенное из этого метода, для помещения экземпляров вашего класса в коллекции, которые используют хэш-алгоритм размещения объектов (например HashMap). Единственными практическими правилами для этого метода (кроме того, что он должен возвращать целое значение) являются два приведенные далее правила. Метод hashCode() должен возвращать:

· Одно и то же значение для одного и того же объекта постоянно.

· Одинаковые значения для одинаковых объектов.

Как правило, возврат значений хэш-кода для некоторых или всех переменных экземпляра объекта является достаточно хорошим способом вычисления хэш-кода. Другим вариантом является преобразование переменных в объекты String, объединение их и возврат хэш-кода для полученного объекта String. Еще одним вариантом является умножение одной или нескольких числовых переменных на некоторую константу для дальнейшего обеспечения уникальности, но это часто излишне.

Перегрузка toString()

Класс Object имеет метод toString(), который наследует каждый создаваемый вами класс. Он возвращает представление вашего объекта в виде String и очень полезен для отладки. Чтобы увидеть действие метода toString(), реализованное по умолчанию, выполните следующий эксперимент в методе main():

public static void main(String[] args) { Adult myAdult = new Adult();   myAdult.addMoney(1); myAdult.addmoney(5);   System.out.println(myAdult); }

Результат, отображаемый в консоли, выглядит следующим образом:

intro.core.Adult@b108475c  

 

Метод println() вызывает метод toString() объекта, переданного ему. Поскольку мы пока не перегрузили toString(), то получаем вывод информации по умолчанию, которой является ID объекта. Каждый объект имеет ID, но он не много скажет вам о самом объекте. Было бы лучше, если бы мы перегрузили toString() для выдачи красиво отформатированного содержимого нашего объекта Adult:

public String toString() { StringBuffer buffer = new StringBuffer();   buffer.append("And Adult with: " + "\n"); buffer.append("Age: " + age + "\n"); buffer.append("Name: " + getName() + "\n"); buffer.append("Race: " + getRace() + "\n"); buffer.append("Gender: " + getGender() + "\n"); buffer.append("Progress: " + getProgress() + "\n"); buffer.append("Wallet: " + getWallet());   return buffer.toString(); }

Мы создаем StringBuffer для создания представления нашего объекта в виде String, затем возвращаем объект String. После выполнения этого примера на консоли должна отобразиться следующая красиво отформатированная информация:

An Adult with: Age: 25 Name: firstname lastname Race: inuit Gender: male Progress: 0 Wallet: [1, 5]

Это значительно удобнее и полезнее, чем загадочный ID объекта.




Дата добавления: 2015-09-11; просмотров: 19 | Поможем написать вашу работу | Нарушение авторских прав

Нужно ли мне это руководство? | Краткая экскурсия по Eclipse | Объявление класса | Объявление класса | Примитивные типы данных | Вызов методов | Арифметические операторы и операторы присваивания | Использование циклов for | Циклы do | Взаимодействие с коллекциями |


lektsii.net - Лекции.Нет - 2014-2024 год. (0.008 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав