Share This
Связаться со мной
Крути в низ
Categories
//☕ Основы Java: выделяем 4 разных роли классов

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

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

osnovy java vydeljaem 4 raznyh roli klassov 1ec4a81 - ☕ Основы Java: выделяем 4 разных роли классов

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

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

Toy.java

         public class Toy {     private int charge = 100; // поле      // метод траты заряда     public boolean spendCharge(int amount) {         if (charge >= amount) {             charge -= amount;             return true;         } else {             return false;         }     }      // метод игры с пользователем     public void play(String user) {         if (spendCharge(10)) {             System.out.println(user + " поиграл в игрушку");         } else {             System.out.println("Нет заряда!");         }     } }      

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

         Toy toy = new Toy(); // создаём объект toy.play("Petya"); // вызываем команду      

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

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

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

ElectricCat.java

         public class ElectricCat extends Toy {      @Override     public void play(String user) {         if (spendCharge(10)) {             System.out.println("Гав-гав для " + user);         } else {             System.out.println("Нет заряда");         }     } }     

ElectricDog.java

         public class ElectricDog extends Toy {     @Override     public void play(String user) {         if (spendCharge(10)) {             System.out.println("Мяу-мяу для " + user);         } else {             System.out.println("Нет заряда");         }     } }     

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

Toy.java

         public abstract class Toy {     private int charge = 100;      public boolean spendCharge(int amount) {         if (charge >= amount) {             charge -= amount;             return true;         } else {             return false;         }     }      // реализацию оставляем на потомках     public abstract void play(String user); }      

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

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

         public static void main(String[] args) {     petyaPlayWith(new ElectricCat()); }  public static void petyaPlayWith(Toy toy) {     toy.play("Petya"); }     

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

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

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

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

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

Utils.java

         public class Utils {     public static String getTimedLine(String msg) {         return "[" + LocalDateTime.now() + "] " + msg;     }      public static boolean isDebugMode; }      

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

         public static void main(String[] args) {     Utils.isDebugMode = true;     System.out.println(Utils.getTimedLine("Debug mode is on!")); }     

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

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

Итог

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

  • 4 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2022 / All rights reserved

    Связаться со мной
    Close