Что такое геттеры и сеттеры в java

Нюансы объектов в Java

1. Свойства: геттер и сеттер

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

Никто детально не изучает документацию по классам, или в ней могут быть не описаны все случаи, поэтому часто могут возникать ситуации, когда данные внутри объекта «портятся», и объект становится не валидным.

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

Если вы хотите, чтобы другие классы могли получать или менять данные внутри объектов вашего класса, вы должны добавить в код вашего класса два метода — get-метод и set-метод. Пример:

Инициализация поля через конструктор

getName() — метод возвращает значение поля name

setName() — метод изменяет значение поля name

Метод get Name() еще называют «геттер поля name», а метод set Name() — «сеттер поля name».

Это очень распространённый подход. В 80-90% всего Java кода вы никогда не увидите публичные переменные класса. Вместо этого они будут объявлены private (ну или protected ), и у каждой переменной будут публичные геттеры и сеттеры.

Этот подход делает код длиннее, но надежнее.

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

А вот как это бы сделал опытный Java-программист:

Код стал длиннее? Безусловно.

Зато в сеттеры и геттеры можно добавить валидацию параметров. Например, можно следить за тем, чтобы x и y всегда были больше нуля (или не меньше нуля). Пример:

2. Время жизни объекта

В Java все устроено немного иначе, и оператора delete в Java нет. Значит ли это, что объекты в Java не удаляются? Нет, удаляются конечно же. Иначе в Java-приложениях быстро закончилась бы память, и ни о каких месяцах беспрерывной работы и речи бы не шло.

В Java процесс удаления объектов полностью автоматизирован – удалением объектов занимается сама Java-машина. Такой процесс называется сборкой мусора (garbage collecting), а механизм, который собирает мусор — сборщиком мусораGarbage Collector или сокращенно GC.

Так как Java-машина узнает, что какой-то объект нужно удалить и когда?

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

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

Циклические ссылки

Предыдущая логика звучит отлично, пока мы не придумаем простой контрпример: у нас есть два объекта, которые ссылаются друг на друга (хранят ссылки друг на друга). Больше никто никаких ссылок на эти объекты не хранит.

К этим объектам нельзя обратиться из остального кода, однако ссылки на них все же есть.

Именно поэтому сборщик мусора делит объекты не на «объекты со ссылками» и «объекты без ссылок», а на достижимые и недостижимые.

Достижимые объекты

Сначала в список достижимых добавляются те объекты, которые 100% живые. Например, текущий поток ( Thread.current() ) или Консоль ( System.in ).

Затем список достижимых объектов пополняют те, на которые ссылаются первые достижимые объекты. Затем те, на кого ссылаются вторые и т.д.

Таким образом, если есть некая группа объектов, которые ссылаются только друг на друга, но от достижимых объектов до них никак добраться нельзя, такие объекты будут считаться мусором и будут удалены.

3. Сборка мусора

Фрагментация памяти

Еще один важный момент, связанный с удалением объектов — фрагментация памяти. Если постоянно создавать и удалять объекты, скоро вся память будет вперемешку: области занятой памяти будут постоянно перемежаться пустыми областями.

И легко может случиться ситуация, когда мы не можем создать большой объект (например, массив на миллион элементов), потому что нет большого куска свободной памяти. Т.е. свободная память вроде и есть, и много, но вот большого цельного куска свободной памяти может и не быть

Оптимизация (дефрагментация) памяти

Java-машина решает эту проблему специфическим образом. Выглядит это примерно так:

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

Выглядит этот процесс примерно так:

Этап 1: После создания объектов

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

Этап 2: Появление «дыр»

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

Этап 3: Устранение «дыр»

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

Таким образом, даже не нужно удалять объекты. Java-машина просто копирует все достижимые объекты в новое место, а всю область памяти со старыми объектами объявляет свободной.

Источник

Есть два типа свойств объекта.

Первый тип это свойства-данные (data properties). Мы уже знаем, как работать с ними. Все свойства, которые мы использовали до текущего момента, были свойствами-данными.

Второй тип свойств мы ещё не рассматривали. Это свойства-аксессоры (accessor properties). По своей сути это функции, которые используются для присвоения и получения значения, но во внешнем коде они выглядят как обычные свойства объекта.

Геттеры и сеттеры

Свойства-аксессоры представлены методами: «геттер» – для чтения и «сеттер» – для записи. При литеральном объявлении объекта они обозначаются get и set :

Геттер срабатывает, когда obj.propName читается, сеттер – когда значение присваивается.

Например, у нас есть объект user со свойствами name и surname :

Снаружи свойство-аксессор выглядит как обычное свойство. В этом и заключается смысл свойств-аксессоров. Мы не вызываем user.fullName как функцию, а читаем как обычное свойство: геттер выполнит всю работу за кулисами.

Давайте исправим это, добавив сеттер для user.fullName :

Дескрипторы свойств доступа

Дескрипторы свойств-аксессоров отличаются от «обычных» свойств-данных.

То есть, дескриптор аксессора может иметь:

Например, для создания аксессора fullName при помощи defineProperty мы можем передать дескриптор с использованием get и set :

Ещё раз заметим, что свойство объекта может быть либо свойством-аксессором (с методами get/set ), либо свойством-данным (со значением value ).

Умные геттеры/сеттеры

Геттеры/сеттеры можно использовать как обёртки над «реальными» значениями свойств, чтобы получить больше контроля над операциями с ними.

Использование для совместимости

У аксессоров есть интересная область применения – они позволяют в любой момент взять «обычное» свойство и изменить его поведение, поменяв на геттер и сеттер.

Давайте его сохраним.

Добавление геттера для age решит проблему:

Теперь старый код тоже работает, и у нас есть отличное дополнительное свойство!

Источник

Геттеры и сеттеры Java. Где применяются, какие у них различия?

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

Геттеры и сеттеры в Java применяются довольно часто. Основная их цель — это обеспечить защиту данным в коде от неправильного внешнего использования.

Они применяются не только в языке Java, но также в С, JavaScript и других языках программирования. То есть геттеры и сеттеры — это довольно распространенное явление в программировании. Но сегодня мы разберем, как используются геттеры и сеттеры именно в языке Java.

Геттеры и сеттеры в Java

Класс « нашей собаки » будет примерно таким:

publc Dog(Strng names, int ages, int weghts) <

public void sayGav() <

Его ко д инг представлен примерно в таком виде:

publc_statcs_void mode(Strng[] ards) <

Геттеры и сеттеры Java: практическое применение

Продолжим нашу тему с собакой. Итак, чуть выше описали возникшую проблему. Резонный вопрос: как она решается?

Итак, данные внутри класса мы защитили. Но получается, что мы ими не сможем воспользоваться? А вдруг нам нужно будет узнать вес нашей запрограммированной программы? Что тогда делать? По идее, нам нужно ка к им-то образом распределить доступность в самом коде: что можно делать, а что — нельзя. Вот тут помогают разрешить всю ситуацию наши геттеры и сеттеры Ява.

Теперь объед и ним вышесказанное и внедрим в наш разработанный для примера скрипт « собачек », и тогда мы должны увидеть следующий результат:

publc_Dog(Strings names, int ages, int weights) <

publc_void setAges(int ages) <

public_void_setWeights(int we i ghts) <

Ничего сложного в таком применении нет, все относительно просто и понятно.

В самой разрабатываемой программе кодинг выглядит примерно таким образом:

public_static void main(Strng[] args) <

Dog jack = new Dog(«Джек», 6, 15);

Strings jackNames = jack.getNames();

int jackAges = jack.getAges();

int jackWeights = jack.getWeights();

Systems.out.prntln(«Кличка собаки: » + jackName);

Systems.out.prntln(«Сколько лет собаке: » + jackAge);

Systems.out.prntln(«Сколько весит собака: » + jackWeight);

И вот что выдаст нам консоль:

Кличка собаки: Джек

Сколько лет собаке: 6

Сколько весит собака: 15

Геттер ы и сеттеры Java простыми словами

Поэтому вместо такой коробки запчастей мы получаем новенький смартфон, который нужно только зарядить, ввести нужный номер и нажать зелененькую кнопочку на экране, чтобы позвонить. Как там подключены провода, процессоры и другие части — нас вообще не волнует. В этом случае производитель смартфона применил «ограничения» к устройству, чтобы мы не смогли его повредить, но при этом с нужной отверткой мы можем добраться и до микросхем внутри.

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

Источник

Геттеры и сеттеры

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Для управляемого доступа к состоянию объекта используют специальные функции, так называемые «геттеры» и «сеттеры».

Геттер и сеттер для воды

На текущий момент количество воды в кофеварке является публичным свойством waterAmount :

Это немного опасно. Ведь в это свойство можно записать произвольное количество воды, хоть весь мировой океан.

Это ещё ничего, гораздо хуже, что можно наоборот – вылить больше, чем есть:

Так происходит потому, что свойство полностью доступно снаружи.

Чтобы не было таких казусов, нам нужно ограничить контроль над свойством со стороны внешнего кода.

Для лучшего контроля над свойством его делают приватным, а запись значения осуществляется через специальный метод, который называют «сеттер» (setter method).

Теперь waterAmount – внутреннее свойство, его можно записать (через сеттер), но, увы, нельзя прочитать.

Для того, чтобы дать возможность внешнему коду узнать его значение, создадим специальную функцию – «геттер» (getter method).

Единый геттер-сеттер

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

При вызове без параметров такой метод возвращает свойство, а при передаче параметра – назначает его.

Единый геттер-сеттер используется реже, чем две отдельные функции, но в некоторых JavaScript-библиотеках, например jQuery и D3, подобный подход принят на уровне концепта.

Итого

Также можно организовать геттеры/сеттеры для свойства, не меняя структуры кода, через дескрипторы свойств.

Задачи

Написать объект с геттерами и сеттерами

Напишите конструктор User для создания объектов:

Должен работать так:

Обратим внимание, что для «геттера» getFullName нет соответствующего свойства объекта, он конструирует ответ «на лету». Это нормально. Одна из целей существования геттеров/сеттеров – как раз и есть изоляция внутренних свойств объекта, чтобы можно было их как угодно менять, генерировать «на лету», а внешний интерфейс оставался тем же.

Добавить геттер для power

Обратим внимание, что ситуация, когда у свойства power есть геттер, но нет сеттера – вполне обычна.

Здесь это означает, что мощность power можно указать лишь при создании кофеварки и в дальнейшем её можно прочитать, но нельзя изменить.

Добавить публичный метод кофеварке

При этом, конечно же, должны происходить все необходимые проверки – на положительность и превышение ёмкости.

Источник

Методы класса, сеттеры и геттеры, public, private, protected

На предыдущих занятиях мы с вами объявляли классы с набором переменных и указывали конструкторы. Пришло время узнать как добавлять функции в класс. По общепринятой терминологии, функции внутри класса называются методами и объявляются согласно следующему синтаксису:

[модификаторы] тип имя_метода([аргументы]) <
// тело метода
>

Например, запишем класс для представления прямоугольника и в нем пропишем метод для вычисления площади прямоугольника:

Здесь square – это обычная функция, объявленная внутри класса Rect и благодаря этому имеет доступ ко всем полям экземпляра этого класса. То есть, если в функции main() создать два таких объекта:

а, затем, вызвать метод square:

то первый вызов будет оперировать данными первого объекта r1, а второй – данными второго объекта r2:

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

В результате, при выводе в консоль:

мы увидим разные значения.

Метод, как и любая Java-функция, может иметь самый разный тип данных и любое число входных аргументов. Например, добавим еще один метод, который будет задавать координату верхнего левого угла:

Здесь тип метода void, т.к. он не возвращает никаких данных и прописаны два аргумента x, y. По аналогии можно добавлять в класс любое число самых разных методов.

Модификаторы доступа

Теперь, когда мы научились объявлять классы и создавать объекты, пришла пора поближе познакомиться с китом ООП по имени инкапсуляция.

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

В рамках этого занятия мы с вами подробно познакомимся с режимами public и private, а о модификаторе protected поговорим после знакомства с механизмом наследования классов.

Геттеры и сеттеры

Давайте вернемся к классу Rect и сделаем так, чтобы поля x1, y1, x2, y2 были скрыты от внешнего пользователя класса и были доступны только изнутри. Для этого нам нужно добавить модификатор private перед типом этих переменных:

Что в итоге изменилось? Смотрите, если теперь попытаться выполнить вот такую команду:

то возникнет ошибка доступа: к полю private нельзя обращаться напрямую через ссылку на объект, то есть, извне. А если убрать этот модификатор в классе Rect, то ошибки не будет. В этом отличие между закрытым (private) полем и общедоступным, который определяется модификатором по умолчанию. Также открытое (публичное) поле можно определять с помощью модификатора public:

Здесь также не будет ошибок, при обращении к переменной x1 напрямую через ссылку на экземпляр класса. В чем же тогда разница между модификатором по умолчанию и public? На уровне одного пакета, то есть, когда файлы программы находятся в одном каталоге, разницы нет. Но, когда два класса расположены в разных пакетах (разных каталогах), то поля с модификатором public будут доступны всюду, а без него (по умолчанию) только в пределах одного пакета (каталога). Во всем остальном они схожи.

Давайте вернем для полей x1, y1, x2, y2 модификатор private и будем полагать, что изменение координат возможно только через конструкторы и методы класса. Для этого определим еще один метод setCoords:

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

То есть, мы сначала создаем объект, а потом определяем координаты прямоугольника. Причем, напрямую обратиться к полям x1, y1, x2, y2 нельзя, мы это можем сделать только через метод setCoords(). Такие методы получили название сеттеры. От префикса set, который обычно записывают в названиях таких методов. Но спрашивается: зачем все так усложнять и не использовать обращение к полям x1, y1, x2, y2 напрямую? Дело в том, что у сеттеров есть одно важное преимущество: они позволяют не только записывать данные в заданные поля, но и выполнять необходимую проверку на корректность переданных данных. Например, мы требуем от пользователя, чтобы координаты прямоугольника были положительными и варьировались в пределах:

Чтобы гарантировать наличие координат в этих пределах, в сеттере достаточно прописать такую проверку:

Добавим закрытый метод isCorrect для проверки корректности значения координаты:

И в самом начале класса пропишем константу MAX_COORD:

Здесь используется ключевое слово static, о котором мы еще будем говорить. Все, теперь мы уверены, что координаты прямоугольника будут находиться в указанных пределах. И это стало возможно использованию закрытых полей и публичному сеттеру setCoords. Также этот пример показывает, что методы класса также можно делать закрытыми (private) и функция isCorrect доступна только внутри класса и не доступна извне. Что вполне логично для нашей текущей реализации.

Нам здесь не хватает еще одного важного метода – для получения текущих координат прямоугольника. Чтобы сейчас не усложнять программу, я запишу четыре таких метода – по одному для каждого значения:

Здесь используется модификатор public для указания общедоступности этих методов, а также префикс get, от которого пошло название – геттеры. То есть, геттеры – это методы, служащие для получения информации из закрытых полей экземпляра класса.

Давайте воспользуемся этими методами и выведем значения координат в консоль:

Вот так реализуется механизм инкапсуляции в классах языка Java.

Подвиг 1. Объявить класс Person для описания сотрудника с полями: Ф.И.О., возраст, вес, номер разряда (целое число от 1 до 5). Прописать конструктор(ы), сеттер(ы) и геттер(ы) для записи значений по сотруднику и считывания данных. Обеспечить корректность представления данных: возраст и вес – положительные числа в пределах [30; 200]; разряд в диапазоне [1; 5]; в Ф.И.О. могут использоваться только буквенные символы, пробел и дефис. Создать несколько таких объектов и убедиться в их корректной работе.

для вычисления суммы и разности двух векторов класса Vec2. Эти методы не должны менять значений векторов, участвующих в операциях сложения и вычитания, а создавать новый с соответствующими значениями.

Подвиг 3. Объявить первый класс Book для представления книги с полями: название, автор, год издания, число страниц. Определить необходимые конструкторы, сеттеры и геттеры для записи и считывания данных (данные должны быть с очевидными ограничениями по диапазону значений). Объявить второй класс Lib, который будет хранить ссылки на книги Book в виде массива:

Book lib[] = new Book[MAX_BOOKS];

где MAX_BOOKS – константа, определяющая максимальное число книг. Обеспечить возможность добавления, удаления и вывода списка книг посредством методов класса Lib. Прямого доступа извне к массиву lib быть не должно.

Видео по теме

Что такое геттеры и сеттеры в java. Смотреть фото Что такое геттеры и сеттеры в java. Смотреть картинку Что такое геттеры и сеттеры в java. Картинка про Что такое геттеры и сеттеры в java. Фото Что такое геттеры и сеттеры в java

#11 Концепция объектно-ориентированного программирования (ООП)

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *