JavaRush /Курси /JAVA 25 SELF /Модифікатори доступу та область видимості змінних

Модифікатори доступу та область видимості змінних

JAVA 25 SELF
Рівень 8 , Лекція 5
Відкрита

1. Вступ

У Java, як і в житті, не все має бути доступним усім і завжди. Уявіть собі квартиру: ви ж не хочете, щоб сусіди ходили у вашу спальню, правда? Так само і в програмах інколи хочеться «закрити двері» до певних змінних або методів, щоб до них не можна було звернутися ззовні.

Для цього в Java існують модифікатори доступу — спеціальні ключові слова, що визначають, де й як можна використовувати змінну або метод, наприклад public чи private.

Основні модифікатори доступу

Модифікатор Де видно?
public
Скрізь, де видно клас (у тому числі в інших пакетах і файлах)
private
Лише всередині того самого класу
(без модифікатора)
Лише в тому самому пакеті (тобто в класах у тому самому каталозі)

Є й інші модифікатори, але про них поговоримо пізніше, коли дійдемо до наслідування.

Приклад на практиці

public class User 
{
    public String name;           // видно всім
    private int age;              // видно лише всередині класу User

    public void sayHello() 
    {
        System.out.println("Привіт, мене звати " + name);
    }

    private void secretMethod() 
    {
        System.out.println("Це секретний метод!");
    }
}

Пояснення:

  • name — видно скрізь, де доступний клас User.
  • age — видно лише всередині самого класу User.
  • sayHello() — публічний метод, його можна викликати з будь-якого іншого класу.
  • secretMethod() — приватний метод, його не можна викликати ззовні.

Як це працює в реальних завданнях?
Припустімо, маємо клас, що описує банківський рахунок. Ми точно не хочемо, щоб хто завгодно міг змінювати баланс напряму! Тому змінну балансу роблять private, а для роботи з нею створюють спеціальні методи.

Чому не варто робити все public?

Може виникнути спокуса: «А давайте зробимо все public, щоб не мучитися!» Але це шлях до хаосу. Уявіть, що хто завгодно може змінювати ваш баланс, імʼя користувача або навіть викликати метод, який мав бути лише для внутрішнього використання. У великих програмах це призводить до помилок і загадкових збоїв.

Золоте правило Java-розробника:
Спочатку робіть усе private, а потім відкривайте назовні лише те, що справді потрібно.

2. Область видимості змінних

Область видимості — це зона коду, де змінна «існує» і може бути використана. Якщо вийти за межі цієї зони, змінна «зникає» — наче її й не було.

У Java є кілька видів змінних за областю видимості:

  • Локальні змінні — оголошені всередині методу або блоку коду { ... }.
  • Параметри методу — оголошені в круглих дужках методу.
  • Поля класу — оголошені всередині класу, але поза методами.

Якщо змінну оголошено всередині { блоку },
вона видна лише всередині цього блоку
і недоступна поза ним.
Область видимості локальної змінної

Локальні змінні

Локальна змінна живе лише всередині методу або блоку, в якому її оголошено.

void printSum(int a, int b) 
{
    int sum = a + b; // локальна змінна
    System.out.println(sum);
}
// sum тут уже не існує!

Спроба звернутися до sum поза методом призведе до помилки компіляції: «Не можу знайти змінну sum».

Параметри методу

Параметри — це теж змінні, але вони живуть лише всередині методу.

void greet(String name) 
{
    System.out.println("Привіт, " + name);
}
// name тут уже не існує!

Поля класу (змінні-члени)

Поля класу оголошуються всередині класу, але поза методами. Вони видимі в усіх методах цього класу.

public class Counter 
{
    private int count = 0; // поле класу

    public void increment() 
    {
        count++; // можемо використовувати поле
    }

    public int getCount() 
    {
        return count; // теж можемо використовувати поле
    }
}

3. Затінення змінних (Shadowing)

Затінення (shadowing) — це ситуація, коли в одній області видимості оголошують змінну (або параметр) з тим самим імʼям, що й у зовнішній області. Усередині цього блоку «нове» імʼя затіняє старе, і до зовнішнього значення вже не можна звернутися напряму.

Приклад затінення:

class ShadowDemo 
{
    int value = 10; // поле класу

    void printValue() 
    {
        System.out.println(value);  // 10 — виводить поле класу
        int value = 5; // локальна змінна затіняє поле класу
        System.out.println(value); // виводить 5, а не 10
    }
}

У цьому прикладі, коли ми пишемо int value = 5;, ми оголошуємо нову локальну змінну, яка має пріоритет над полем класу з тим самим імʼям. При зверненні до value всередині методу printValue() буде використовуватися локальна змінна, а не поле класу.

Якщо все ж потрібно звернутися до статичного поля класу, використовуйте імʼя класу як префікс:

class ShadowDemo 
{
    static int value = 10; // статичне поле класу 

    void printValue() 
    {
        System.out.println(value);      // 10 — поле класу
        int value = 5;
        System.out.println(value);      // 5 — локальна змінна
        System.out.println(ShadowDemo.value); // 10 — статичне поле класу, доступ через «ShadowDemo»
    }
}

Якщо треба звернутися до нестатичного поля класу, використовують ключове слово this. Воно вказує на поточний екземпляр обʼєкта.

class ShadowDemo 
{
    int value = 10;

    void printValue() 
    {
        System.out.println(value);      // 10 — поле класу
        int value = 5;
        System.out.println(value);      // 5 — локальна змінна
        System.out.println(this.value); // 10 — поле класу, доступ через 'this'
    }
}

4. Практика: модифікатори доступу й область видимості

Продовжмо розвивати навчальний застосунок: проста система обліку студентів. Додамо поля й методи з різними модифікаторами доступу.

Приклад: клас Student

public class Student 
{
    public String name;        // імʼя студента (видно всім)
    private int age;           // вік (видно лише всередині класу)

    public Student(String name, int age) 
    {
        this.name = name;
        this.age = age;
    }

    public void sayHello() 
    {
        System.out.println("Привіт, мене звати " + name);
    }

    private void printSecret() 
    {
        System.out.println("Мій вік: " + age);
    }

    public void revealSecret() 
    {
        printSecret(); // можна викликати приватний метод усередині класу
    }
}

Використання класу Student

public class Main 
{
    public static void main(String[] args) 
    {
        Student s = new Student("Іван", 20);
        s.sayHello();       // ОК: публічний метод
        s.revealSecret();   // ОК: публічний метод, який викликає приватний всередині

        s.age = 30;      // Помилка! Поле age приватне

        s.printSecret(); // Помилка! Метод printSecret приватний
    }
}

5. Типові помилки під час роботи з модифікаторами доступу та областю видимості

Помилка № 1: Усе public — і привіт, хаос!
Якщо зробити всі поля й методи публічними, ви ризикуєте втратити контроль над тим, хто й як змінює ваші дані. Робіть поля private і відкривайте назовні лише необхідне.

Помилка № 2: Спроба використати змінну поза її областю видимості.
Наприклад, ви оголосили змінну всередині методу, а потім намагаєтеся звернутися до неї ззовні — отримаєте помилку компіляції. Локальні змінні живуть лише у своєму блоці { ... }.

Помилка № 3: Конфлікт імен (затінення змінних).
Якщо в методі оголосити змінну з тим самим імʼям, що й поле класу, легко заплутатися, яку змінну ви використовуєте. Використовуйте this, щоб явно вказати на поле класу: this.value.

Помилка № 4: Спроба звернутися до private-методу або поля з іншого класу.
Якщо метод або поле позначені як private, вони доступні лише всередині того ж класу. Спроба звернутися до них ззовні спричинить помилку компіляції.

Помилка № 5: Забули про область видимості в циклі або блоці.
Змінна, оголошена всередині циклу або будь-якого блоку { }, живе лише в цьому блоці. Поза блоком вона не існує.

1
Опитування
Методи, рівень 8, лекція 5
Недоступний
Методи
Оголошення та виклик методів
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ