Урок 4. Экземпляры и статические члены Java


В этой статье из моего курса уроков по Java я буду обсуждать операторы импорта, члены экземпляра и конструктор по умолчанию.

Как вы можете видеть ниже, я создал класс Person, и в этом классе у нас есть переменная экземпляра с именем ‘personName’ и метод экземпляра с именем helloWorld(). Наши переменные и методы называются членами экземпляра класса.

package ru.upread.javacourse;

import ru.upread.javacourse.attributes.Name;

public class Person {

    private Name personName;

    public String helloWorld() {
        return "Hello World";
    }
}
Так что же такое экземпляр? Экземпляр - это единичное «появление» объекта. В то время как существует только один класс, существует много экземпляров класса: объекты. Например, мы можем иметь сотни и сотни различных объектов человека. Каждый объект Person имеет собственный экземпляр класса Name и собственную версию метода helloWorld(). Кроме переменных экземпляра и методов, могут быть также статические. Все экземпляры класса совместно используют статические переменные или статические методы класса.

Переменные и метод также называются "членами". Член, принадлежащий экземпляру, называется членом экземпляра; член, принадлежащий классу (статическая переменная или метод), называется членом класса.

Помимо членов экземпляра существуют также статические члены или члены класса. Переменные и методы класса создаются путем добавления ключевого слова static к методу или переменной.

package ru.upread.javacourse;

import ru.upread.javacourse.attributes.Name;

public class Person {

    private Name personName;

    private static Planet homePlanet;

    public static String helloWorld() {
        return "Hello World";
    }
}
Если мы изменим значение homePlanet для одного экземпляра Person, все остальные экземпляры также изменят свои значения. Это продвинутая тема, которая будет обсуждаться позже более подробно. А пока просто знайте, что без ключевого слова static наши методы и переменные - это переменные и методы экземпляра.



Конструкторы

Следующее, что мы сделаем в нашей программе, это напишем конструктор для нашего объекта Person. Я уже упоминал о конструкторах, но если говорить более подробно, конструкторы - это код, который используется для создания объектов. Конструкторы начинаются с короткого имени класса, за которым следуют скобки, содержащие любые параметры, а затем открывающая фигурная скобка и закрывающая фигурная скобка. В промежутках между фигурными скобками вы присваиваете значения переменным экземпляра и вызываете любые методы, которые должны быть вызваны при создании объекта этого типа класса. Конструкторы могут выглядеть как методы, но они не возвращают значения и не имеют тега void. В классе может быть сколько угодно конструкторов, но каждому конструктору необходим уникальный набор параметров.

Если вы не пишете конструктор для своего класса, компилятор неявно включает конструктор, не содержащий параметров.

Обратите внимание – пустой конструктор без параметров, добавленный компилятором неявно, называется конструктором по умолчанию. Как ни странно, тот же беспараметрический пустой конструктор, явно написанный в коде, не называется “конструктором по умолчанию”.

Полагаться на неявно добавленный конструктор по умолчанию, на мой взгляд, немного проблематично. Если вы добавите (позже) конструктор, содержащий один или несколько параметров, конструктор по умолчанию не будет добавлен компилятором. Я называю такие автоматические действия компилятора "магическими", так как они не всегда понятны и легко приводят к путанице.

Поэтому я обычно рекомендую вам всегда писать свой собственный беспараметрический пустой конструктор в коде, если он вам нужен.

Никогда не полагайтесь на компилятор, чтобы добавить его. Однако это может привести к дальнейшей путанице относительно того, почему вы добавили избыточный конструктор без параметров. Другой разработчик может даже просто” расширить " его позже, добавив параметры в конструктор без параметров - эффективно удаляя конструктор без параметров из вашего класса.

Поэтому я предлагаю вам использовать следующий подход по умолчанию: если вам нужен пустой конструктор, добавьте его явно. Затем оставьте комментарий, документирующий, почему вы явно добавили пустой конструктор в этом случае. Приведу конкретный пример: пустые конструкторы часто нужны, когда используются определенные фреймворки, например Hibernate.

Для нашего класса Person я собираюсь создать конструктор, который устанавливает значение personName, заданное значением. Если вы посмотрите на пример ниже, я создал две различные переменные, называемые personName. Один из них - переменная экземпляра в классе, а другой-аргумент в нашем конструкторе. Чтобы дифференцировать их, мы должны добавить this. в переменную экземпляра personName. Сюда, сюда.personName устанавливается в значение personName, полученное в качестве аргумента в конструкторе.

package ru.upread.javacourse;

import ru.upread.javacourse.attributes.Name;

public class Person {

    private Name personName;

    private static Planet homePlanet;

    public Person(Name personName) {
        this.personName = personName;
    }

    public static String helloWorld() {
        return "Hello World";
    }
}
Поскольку мы создали конструктор, компилятор не будет автоматически использовать конструктор по умолчанию. Теперь всякий раз, когда кто-то вызывает конструктор для создания объекта типа person, он должен включать имя personName, поскольку это единственный конструктор, доступный для него.

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

Создание тестового случая

Как я уже говорил, метод тестирования аннотируется с помощью @Test. Эта аннотация вызывает тестовый класс из фреймворка JUnit и настраивает тестовую среду в нашей виртуальной машине Java (JVM). Давайте создадим второй метод в нашем тестовом классе, чтобы мы могли увидеть, как работает наш тестовый класс немного глубже. В нашем тестовом классе я собираюсь создать второй метод, shouldReturnHelloMarcus().

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class PersonTest {

    @Test
    public void shouldReturnHelloWorld() {
        Person person = new Person();
        assertEquals("Hello World", person.helloWorld() );
    }

    @Test
    public void shouldReturnHelloMarcus() {
        Person marcus = new Person();
        assertEquals("Hello Marcus", marcus.hello(“Marcus”));
    }
}
После того, как я создал этот метод, я собираюсь создать объект типа Person с именем переменной экземпляра marcus. Если мы попытаемся выполнить это, мы получим ошибку компиляции, как я уже отмечал ранее, потому что наш метод shouldReturnHelloWorld () пытается создать объект Person с конструктором по умолчанию. Чтобы избавиться от этой ошибки, мы просто создадим конструктор по умолчанию в нашем классе.

package ru.upread.javacourse;

import ru.upread.javacourse.attributes.Name;

public class Person {

    private Name personName;

    private static String homePlanet;

    public Person() {
       /*конструктор по умолчанию, необходимый для Hibernate */
    }

}
Комментарии

Как я уже говорил, позже может возникнуть путаница относительно того, почему вы создали этот конструктор по умолчанию. Вы можете даже забыть причину сами, дальше по линии. Добавление комментариев к коду предотвратит путаницу. Они игнорируются компилятором, поэтому, кроме обозначения самого комментария, требуется немного синтаксиса. Помните, однако, чтобы использовать комментарии экономно, и никогда не комментировать очевидное. Переменная person не нуждается в комментарии, который говорит "это человек"!

Вместо этого вы всегда должны стремиться выразить свое намерение в самом коде. Например, метод, который добавляет два числа и называется add(), ясно показывает, что он делает, и, вероятно, не требует комментария для описания метода. Есть несколько исключений из этого правила, но обычно комментарий используется как исправление для плохого кода, который не правильно выражает свое намерение.

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

В Java можно определить два типа комментариев: многострочные комментарии и однострочные комментарии. Многострочные комментарии начинаются с "/ * "и заканчиваются"*/". Между этими двумя символами вы можете написать столько строк комментариев, сколько захотите.

Однострочный комментарий начинается с '//' и продолжается до конца строки кода. В общем, я рекомендую вам всегда использовать многострочные комментарии, потому что если однострочный комментарий слишком длинный, он будет разбит при автоматическом форматировании кода, что может происходить довольно часто в команде разработчиков. Подробнее по комментариям Java можно почитать здесь.

Теперь мы создадим конструктор по умолчанию для класса Person. Внутри конструктора по умолчанию я добавил комментарий. Я также собираюсь создать метод hello (), который мы вызвали в нашем тестовом классе. Он получает один аргумент - имя человека, с которым мы "здороваемся".

Объединение строк

В нашем методе hello () мы возвращаем строку. Однако строка, которую мы возвращаем, не всегда будет одной и той же. Он всегда будет начинаться с "привет", за которым следует имя человека. Мы должны превратить эти две отдельные строки в одну строку, которую мы возвращаем. Этот процесс сложения строк называется конкатенацией.

Для этого мы помещаем '+' между двумя строками, создавая одну большую строку. Теперь наш метод вернет "Привет", а затем имя человека. Я оставил скрытую ошибку в примере выше, которая приведет к провалу нашего теста. Посмотрим, сможете ли вы её найти.

Тестирование нашего кода и исправление ошибок

Теперь давайте выполним наш тестовый класс. Как и ожидалось, ничего не вышло. Причина в том, что существует несоответствие между нашим ожидаемым значением, которое было “Hello Marcus”, и фактическим значением “HelloMarcus”. Когда мы соединили наши две строки, мы забыли включить пробел между ними. Чтобы исправить это, все, что нам нужно сделать, это добавить пробел после слова “Привет”.

public static String hello(String name) {
    return "Hello " + name;
}
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, уроки по java, java




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.



Несколько полезных сочетаний клавиш для IntelliJ IDEA
Обновляем файловую систему с помощью diff и patch
Программа "Новогодняя ёлочка"