Поля класса Java – подробно для новичков
Поле Java – это переменная внутри класса. Например, в классе, представляющем сотрудника, класс Работник может содержать следующие поля:
Синтаксис объявления поля
[access_modifier] [static] [final] type name [= initial value] ;
Квадратные скобки [] вокруг некоторых ключевых слов означают, что этот параметр является необязательным. Требуется только тип и имя.
- Сначала модификатор доступа может быть объявлен для него. Он определяет, какие классы объектов могут получить доступ к полю. В приведенном выше примере Employee не было модификаторов доступа.
- Тип данных должен быть назначен. В приведенном выше примере Employee использовались типы данных String, int и Date.
- Может быть статическим. В Java статические поля принадлежат классу, а не экземплярам класса. Таким образом, все экземпляры любого класса будут иметь доступ к одной и той же переменной статического поля.
- Нестатическое значение может быть различным для каждого объекта (экземпляра) класса.
- Может быть объявлено как окончательное или нет. В первом случае не может изменить свое значение. Во-втором – должно иметь начальное значение, назначенное ему, и после установки значение не может быть изменено снова. Окончательное поле часто также объявляется статическим, объявляемым как static и final, также называемым « константой ».
- Имеет имя. Вы можете выбрать это имя свободно, но есть некоторые ограничения на то, какие символы могут содержать имя.
- Можете при желании установить начальное значение для него.
Некоторые из приведенных выше вариантов более подробно описаны в следующих разделах.
Модификаторы доступа
Модификатор доступа определяет, можно ли получить доступ к полю другим классам, кроме класса, владеющего полем. Существует четыре вида:
- частный доступ – означает, что только код внутри самого класса может получить доступ к этому полю;
- к пакету – означает, что только код внутри самого класса или других классов в том же пакете может получить доступ к полю. Вы на самом деле не пишете модификатор пакета. Оставляя любой модификатор доступа, модификатор доступа по умолчанию устанавливается в область действия пакета;
- защищенный доступ – похож на модификатор пакета, за исключением того, что подклассы класса также могут обращаться к полю, даже если подкласс не находится в том же пакете;
- открытый доступ – означает, что к полю могут обращаться все классы Java в вашем приложении.
Вышеупомянутое использование модификаторов доступа к полю используется только в этом примере. Вы можете не использовать модификаторы доступа в одном классе. Чаще всего применяются частные и защищенные. Для простых классов переноса данных все поля объявляют открытыми.
Статические и нестатические поля
Поле Java может быть статическим или нестатическим. Статическое поле принадлежит классу. Таким образом, независимо от того, сколько объектов вы создаете для этого класса, будет существовать только одно поле, расположенное в классе, и значение этого поля одинаково, независимо от того, к какому объекту он доступен. Вот диаграмма, иллюстрирующая статические поля:
Вы определяете статическое поле, используя ключевое слово static в объявлении поля, например:
Статические поля расположены в классе, поэтому вам не нужен экземпляр для доступа к статическим полям. Вы просто пишете имя впереди, вот так:
Customer.staticField1 = "value"; System.out.println(Customer.staticField1);
Нестатические поля Java, с другой стороны, расположены в экземплярах класса. Каждый экземпляр может иметь свои собственные значения для этих полей. Вот диаграмма, иллюстрирующая нестатические поля:
Вы определяете нестатическое поле, просто опуская ключевое слово static. Вот пример:
Для доступа к нестатическому полю вам необходим экземпляр(объект), к которому вы можете получить доступ к нему:
Customer customer = new Customer(); customer.field1 = "value"; System.out.println(customer.field1);
Окончательные
Поле может быть объявлено окончательным. Не может иметь измененное значение после назначения. Для объявления добавляете ключевое слово final:
Значение поля field1 не может быть изменено сейчас. Это означает, что даже если поле принадлежит объектам, вы не можете изменять значение поля от объекта к объекту.
Если вы все равно не можете изменить значение конечного поля, во многих случаях имеет смысл также объявить его статическим. Таким образом, он существует только в классе, а не в каждом объекте:
Поскольку статические конечные поля часто используются в качестве констант, соглашение об именах должно записывать имя поля в верхнем регистре и разделять слова подчеркиванием _. Вот пример:
Именование
Имя поля используется для ссылки на это поле из вашего кода:
Customer customer = new Customer(); customer.city = "New York"; System.out.println(customer.city);
- Первая строка создает новый объект Customer (экземпляр класса Customer) и сохраняет его в переменной с именем customer.
- Вторая строка присваивает значение String New York для поля города объектов Customer.
- Третья строка выводит значение поля города на вывод консоли.
Ограничения именования и соглашения именования для полей такие же, как и для любых других типов переменных.
Начальное значение
Поле может иметь начальное значение, которое присваивается при создании в JVM. Статические поля создаются при загрузке класса. Класс загружается при первом обращении к нему в вашей программе. Нестатические поля создаются при создании объекта, которому они принадлежат.
Вот пример поля, объявленного с начальным значением:
Хотите ли вы инициализировать свои поля (и другие переменные) начальным значением, решать вам.
Приватное поле класса java
Все члены класса в языке Java — поля и методы — имеют модификаторы доступа. В прошлых темах мы уже сталкивались с модификатором public . Модификаторы доступа позволяют задать допустимую область видимости для членов класса, то есть контекст, в котором можно употреблять данную переменную или метод.
В Java используются следующие модификаторы доступа:
- public : публичный, общедоступный класс или член класса. Поля и методы, объявленные с модификатором public, видны другим классам из текущего пакета и из внешних пакетов.
- private : закрытый класс или член класса, противоположность модификатору public. Закрытый класс или член класса доступен только из кода в том же классе.
- protected : такой класс или член класса доступен из любого места в текущем классе или пакете или в производных классах, даже если они находятся в других пакетах
- Модификатор по умолчанию . Отсутствие модификатора у поля или метода класса предполагает применение к нему модификатора по умолчанию. Такие поля или методы видны всем классам в текущем пакете.
Рассмотрим модификаторы доступа на примере следующей программы:
public class Program < public static void main(String[] args) < Person kate = new Person("Kate", 32, "Baker Street", "+12334567"); kate.displayName(); // норм, метод public kate.displayAge(); // норм, метод имеет модификатор по умолчанию kate.displayPhone(); // норм, метод protected //kate.displayAddress(); // ! Ошибка, метод private System.out.println(kate.name); // норм, модификатор по умолчанию System.out.println(kate.address); // норм, модификатор public System.out.println(kate.age); // норм, модификатор protected //System.out.println(kate.phone); // ! Ошибка, модификатор private >> class Person < String name; protected int age; public String address; private String phone; public Person(String name, int age, String address, String phone)< this.name = name; this.age = age; this.address = address; this.phone = phone; >public void displayName() < System.out.printf("Name: %s \n", name); >void displayAge() < System.out.printf("Age: %d \n", age); >private void displayAddress() < System.out.printf("Address: %s \n", address); >protected void displayPhone()< System.out.printf("Phone: %s \n", phone); >>
В данном случае оба класса расположены в одном пакете — пакете по умолчанию, поэтому в классе Program мы можем использовать все методы и переменные класса Person, которые имеют модификатор по умолчанию, public и protected. А поля и методы с модификатором private в классе Program не будут доступны.
Если бы класс Program располагался бы в другом пакете, то ему были бы доступны только поля и методы с модификатором public.
Модификатор доступа должен предшествовать остальной части определения переменной или метода.
Инкапсуляция
Казалось бы, почему бы не объявить все переменные и методы с модификатором public , чтобы они были доступны в любой точке программы вне зависимости от пакета или класса? Возьмем, например, поле age, которое представляет возраст. Если другой класс имеет прямой доступ к этому полю, то есть вероятность, что в процессе работы программы ему будет передано некорректное значение, например, отрицательное число. Подобное изменение данных не является желательным. Либо же мы хотим, чтобы некоторые данные были достуны напрямую, чтобы их можно было вывести на консоль или просто узнать их значение. В этой связи рекомендуется как можно больше ограничивать доступ к данным, чтобы защитить их от нежелательного доступа извне (как для получения значения, так и для его изменения). Использование различных модификаторов гарантирует, что данные не будут искажены или изменены не надлежащим образом. Подобное сокрытие данных внутри некоторой области видимости называется инкапсуляцией .
Так, как правило, вместо непосредственного применения полей используют методы доступа. Например:
public class Program < public static void main(String[] args) < Person kate = new Person("Kate", 30); System.out.println(kate.getAge()); // 30 kate.setAge(33); System.out.println(kate.getAge()); // 33 kate.setAge(123450); System.out.println(kate.getAge()); // 33 >> class Person < private String name; private int age = 1; public Person(String name, int age)< setName(name); setAge(age); >public String getName() < return this.name; >public void setName(String name) < this.name = name; >public int getAge() < return this.age; >public void setAge(int age) < if(age >0 && age < 110) this.age = age; >>
И затем вместо непосредственной работы с полями name и age в классе Person мы будем работать с методами, которые устанавливают и возвращают значения этих полей. Методы setName, setAge и наподобие еще называют мьютейтерами (mutator), так как они изменяют значения поля. А методы getName, getAge и наподобие называют аксессерами (accessor), так как с их помощью мы получаем значение поля.
Причем в эти методы мы можем вложить дополнительную логику. Например, в данном случае при изменении возраста производится проверка, насколько соответствует новое значение допустимому диапазону.
Declaring Member Variables
The Bicycle class uses the following lines of code to define its fields:
public int cadence; public int gear; public int speed;
Field declarations are composed of three components, in order:
- Zero or more modifiers, such as public or private .
- The field’s type.
- The field’s name.
The fields of Bicycle are named cadence , gear , and speed and are all of data type integer ( int ). The public keyword identifies these fields as public members, accessible by any object that can access the class.
Access Modifiers
The first (left-most) modifier used lets you control what other classes have access to a member field. For the moment, consider only public and private . Other access modifiers will be discussed later.
- public modifierthe field is accessible from all classes.
- private modifierthe field is accessible only within its own class.
In the spirit of encapsulation, it is common to make fields private. This means that they can only be directly accessed from the Bicycle class. We still need access to these values, however. This can be done indirectly by adding public methods that obtain the field values for us:
public class Bicycle < private int cadence; private int gear; private int speed; public Bicycle(int startCadence, int startSpeed, int startGear) < gear = startGear; cadence = startCadence; speed = startSpeed; >public int getCadence() < return cadence; >public void setCadence(int newValue) < cadence = newValue; >public int getGear() < return gear; >public void setGear(int newValue) < gear = newValue; >public int getSpeed() < return speed; >public void applyBrake(int decrement) < speed -= decrement; >public void speedUp(int increment) < speed += increment; >>
Types
All variables must have a type. You can use primitive types such as int , float , boolean , etc. Or you can use reference types, such as strings, arrays, or objects.
Variable Names
All variables, whether they are fields, local variables, or parameters, follow the same naming rules and conventions that were covered in the Language Basics lesson, VariablesNaming.
In this lesson, be aware that the same naming rules and conventions are used for method and class names, except that
- the first letter of a class name should be capitalized, and
- the first (or only) word in a method name should be a verb.