Основы Java выделяем 4 разных роли классов

Основы Java выделяем 4 разных роли классов

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

А вот так этот класс используется для создания объектов:

Здесь класс послужил чертежём, описывающим внутреннее устройство и поведение объектов этого типа (экземпляров класса).

2. Класс как основа схемы для объектов

Представим себе, что мы хотим два вида объектов игрушек с разным поведением в команде play : например, электро-собаки гавкают во время игры, а электро-кошки мяукают. Создадим два класса ( ElectricCat и ElectricDog ), которые будут отличаться только поведением метода play . Чтобы не дублировать код работы с зарядом (поле charge и метод spendCharge ), воспользуемся механизмом наследования, указав у новых классов класс Toy родительским:

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

3. Класс как список требований к объектам (полиморфизм)

Использование классов не ограничивается созданием объектов, класс указывают и в качестве типа L-value (т.е. ячейки, в которую кладут значения, например, переменная, поле, параметр и тп). При этом в качестве значения в эту ячейку необязательно класть объект того же самого класса: благодаря полиморфизму подойдёт и другой наследник. На примере наших классов это будет выглядеть так:

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

Класс Toy в роли типа L-value превратился в список требований к объектам – значению необходимо иметь в наличии необходимые методы и быть наследником этого типа. Чтобы лучше увидеть отличие этой роли от предыдущей, можно сделать класс полностью абстрактным (без полей и только с абстрактными методами), из-за чего у него не будет реализации, которой можно поделиться с наследниками (кроме самой необходимости реализовать абстрактные методы).

Эта роль оказалась настолько важной, что для таких очень абстрактных классов ввели отдельный инструмент в виде интерфейсов с особыми механиками их наследования классами, в терминах джавы – имплементации; но позже в интерфейсы были добавлены и методы с реализацией через модификатор default .

4. Класс как пространство имён

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

Для обращения к таким полям и методам объекты класса Utils не нужны, используется имя класса напрямую:

При этом если нестатическое поле присутствует по экземпляру в каждом объекте класса, то статическое поле сущетвует в единственном экземпляре.

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

Классы в джаве используются не только как схемы для будущих объектов одноимённого типа, но и являются основой для других таковых схем, регламентируют взаимодействие с L-value или служат пространством имён для программирования в процедурном стиле. Надеемся, наша статья помогла вам в этом разобраться и оказалась полезной. Удачи в обучении!