Рубрики
Без рубрики

Разница между публичным и частным в Java

При первом изучении Java многие студенты, как правило, сталкиваются с ключевыми словами private и public. Добро пожаловать в мир модификаторов доступа!. С пометкой java, новички, кодирование, программирование.

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

Проблема, С Которой Сталкиваются Студенты

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

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

Но сначала давайте взглянем на пример некоторого кода, который почти наверняка вызовет некоторые вопросы о модификаторах доступа:

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

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

В результате мы часто вынуждены рассказывать студентам что-то вроде:

Не беспокойтесь о внешних четырех линиях. Просто поместите любой код, который вы хотите выполнить, в средний блок.

— Профессора Компьютерных Наук Повсюду

Конечно, такая линия рассуждений оставляет желать лучшего, если вы новичок. Например, что делает любая из этих четырех внешних линий? Что общедоступно ? Как насчет статического , Строки[] или System.out.println ?

К счастью, сегодня я расскажу о части модификатора доступа.

Объяснение, Которого Желают Студенты

На этом этапе давайте поговорим о модификаторах доступа на высоком уровне.

Обзор модификатора доступа

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

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

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

Это идея высокого уровня, лежащая в основе модификаторов доступа. Мы используем их, чтобы раскрыть или скрыть определенные функции для улучшения общего пользовательского опыта.

Заблуждения

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

Подумайте о примере со стеклоочистителем лобового стекла. Когда мы включаем ваши дворники, мы ожидаем, что они оба будут двигаться с одинаковой скоростью. Без ограниченного доступа мы могли бы изменить скорость одного из дворников по умолчанию. Затем, в следующий раз, когда мы пойдем включать дворники… БАМ! Чтобы избежать этой проблемы, мы инкапсулируем (или скрыть) тот факт, что у нас есть два отдельных стеклоочистителя в одном открытом (общедоступном) методе.

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

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

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

Ключевые слова

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

T T T Тот же Класс T
T F T Другой класс в одной упаковке T
T F T Подкласс в том же пакете T
T F F Другой класс в другой упаковке F
T F T Подкласс в другом пакете F

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

  1. частный
  2. пакет-закрытый (по умолчанию)
  3. защищенный
  4. общественный

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

Классификация действий как публичных или частных

Используя предыдущий пример с метанием мяча, давайте попробуем выяснить, какой модификатор доступа будет уместен в различных ситуациях:

  • общественный
    • бросать
    • ловить
    • бросать жребий
    • подача
  • частный
    • вращать Рычаг
    • перевод вершин
    • подобрать Мяч
    • рассчитать объем

Обратите внимание, что все действия высокого уровня являются общедоступными, а действия более низкого уровня являются частными. Это потому, что мы не обязательно хотим выставлять действия более низкого уровня на всеобщее обозрение. Но почему бы и нет? Давайте взглянем на другой пример.

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

Что бы произошло, если бы мы могли получить доступ к таким действиям, как setGravity или установить мяч ? Как изменились бы наши действия на высоком уровне, такие как бросок или поймать ?

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

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

Определяемые пользователем классы

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

Привет, Мир, Возвращенный

Теперь, когда мы увидели некоторые объяснения высокого уровня, давайте вернемся к нашему примеру Hello World.

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

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

Чтобы сделать вещи немного интереснее, давайте обернем печать в ее собственный частный метод:

public class HelloWorld {
  public static void main(String[] args) {
    printHelloWorld();
  }

  private static void printHelloWorld() {
    System.out.println("Hello, World!"); 
  }
}

Если мы попытаемся запустить это решение, мы заметим, что поведение вообще не изменилось. Это потому, что частные методы могут использоваться в их собственном классе. Снаружи Привет, мир , однако, никто не знает, что printHelloWorld() даже существует. На самом деле, мы могли бы попытаться вызвать метод непосредственно из другого класса в той же папке, и мы бы столкнулись с ошибкой:

public class CallPrivateMethod {
  public static void main(String[] args) {
    HelloWorld.printHelloWorld();  // ERROR
  }
}

Как мы видим, мы скрыли функцию печати, чтобы ее мог использовать только класс HelloWorld . Если бы по какой-то причине мы сделали метод print Hello World() общедоступным, мы могли бы запустить его просто отлично.

Стеклоочистители лобового стекла

Теперь давайте продвинем эту концепцию еще на шаг вперед, фактически внедрив стеклоочистители на Java (по крайней мере, на высоком уровне). Для начала мы создадим класс car, в котором есть частный метод для одного стеклоочистителя и общедоступный метод для обоих стеклоочистителей:

public class Car {
    private boolean[] wipers;

    public Car() {
        this.wipers = new boolean[2];
    }

    private void turnOnWiper(int index) {
        this.wipers[index] = true;
    }

    public void turnOnWipers() {
        for (int i = 0; i < this.wipers.length; i++) {
            this.turnOnWiper(i);
        }
    }
}

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

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

public class CarBuilder {
    public static void main(String[] args) {
        Car car = new Car();
        car.turnOnWipers(); // Turns on wipers!
        car.turnOnWiper(1); // Compilation ERROR
        car.wipers[0] = false; // Compilation ERROR
    }
}

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

А теперь, почему бы тебе самому не попробовать расширить класс? Например, я рекомендую добавить способ отключения дворников. Затем вы можете написать новый закрытый метод для отключения отдельных стеклоочистителей, или вы можете обнаружить, что имеет смысл реорганизовать метод turnOnWiper , чтобы он также принимал логическое значение. Поскольку пользователь никогда не видит эти методы, у вас есть полный контроль над базовой реализацией. Счастливого кодирования!

Открытый форум

Надеюсь, это поможет вам понять разницу между частными и общедоступными ключевыми словами и почему мы их используем. Если нет, я открыт для любых отзывов и вопросов, которые у вас могут возникнуть. Не стесняйтесь использовать комментарии ниже, чтобы начать небольшой диалог. И если это вам вообще помогло, поделитесь этим со своими друзьями. Я всегда ценю поддержку!

Оригинал: “https://dev.to/renegadecoder94/the-difference-between-public-and-private-in-java-3g2e”